2013-10-12 110 views
2

考慮以下內容,其中有些內容是通過多層添加到載體:傳遞參數爲const&或&&

class A { 
public: 
    void Add(Content c) { 
    // Considerable amount of checking code here. 
    v.push_back(c); 
    } 
private: 
    std::vector<Content> v; 
}; 

class B { 
public: 
    void Add(Content c) { 
    // Considerable amount of additional code here. 
    a.Add(c); 
    } 
private: 
    A a; 
}; 

class C { 
public: 
    void Add(Content c) { 
    // Considerable amount of additional code here. 
    b.Add(c); 
    } 
private: 
    B b; 
}; 

這可以繼續,但你在這裏看到這一點。我希望通過複製或移動添加內容,即通過push_back(const Content &)或push_back(Content & &)添加內容。調用者應該能夠透過電話:

C c; 
Content z; 
c.Add(z); 

c.Add(move(z)); 

,並得到副本數量最少。

有沒有一種方法來實現這個沒有重複的額外的代碼,並沒有使添加功能模板功能?

回答

0

您可以添加兩種方法旁邊簽名:

void Add(Content && c); 
void Add(Content & c); 

其他選項是普遍的參考,但你需要的模板。

+0

這不需要代碼重複(請參閱問題)? –

1

用於重載右值和左值兩種方法一種方法:

void Add(const Content & c); 
void Add(Content && c); 

使用完美轉發你能避免兩個重載。你應該把所有add方法是這樣的:

template<typename T> 
void add(T&& a) 
{ 
    b.Add(std::forward<T>(a)); 
} 

 

另一種方法,這是更好(IMO)正在Content移動。如果Content是真實的類(不適用於模板的佔位符),你可以做到這一點:

class Content 
{ 
public: 
    Content(const Content &); 
    Content(Content &&); 

    Content &operator=(Content); // Copy and swap idiom! 

    ~Content(); 
}; 

之後,你可以重新寫Add方法象下面這樣:

void Add(Content c) { 
    b.Add(std::move(c)); 
      ^^^^^^^^^^^^ 
} 

這種方法的優點是,你可以透明地從來電方移動或複製。

+0

如果我有n層。我會在所有Add方法中使用按值調用嗎?或者只是在最外面,其他都是右值參數?如果第一個選項:我能確定所有的副本都會被編譯器忽略嗎? –

+0

第一種解決方案會導致代碼重複,不是嗎? Add函數包含更多的代碼,而不僅僅是內部的Add調用。 –

+0

@KitFisto:對於第一種解決方案,通過完美轉發,您可以避免代碼重複。爲什麼不讓'Content'動起來擺脫重複? – deepmax

相關問題