2012-06-14 43 views
8

在以下代碼中,可變參數構造函數被調用兩次。如何在適當的情況下調用拷貝構造函數而不是可變參數構造函數的單個參數版本?如何獲取通過可變參數構造函數調用的複製構造函數?

#include <iostream> 

struct Foo 
{ 
    Foo(const Foo &) 
    { 
     std::cout << "copy constructor\n"; 
    } 

    template<typename... Args> 
    Foo(Args&&... args) 
    { 
     std::cout << "variadic constructor\n"; 
    } 

    std::string message; 
}; 

int main() 
{ 
    Foo f1; 
    Foo f2(f1); // this calls the variadic constructor, but I want the copy constructor. 
} 

回答

9

這實際上與構造函數是可變參數無關。與非可變參數的構造函數模板下面的類具有相同的行爲:

struct Foo 
{ 
    Foo() { } 

    Foo(const Foo& x) 
    { 
     std::cout << "copy constructor\n"; 
    } 

    template <typename T> 
    Foo(T&& x) 
    { 
     std::cout << "template constructor\n"; 
    } 

}; 

的問題是,構造函數模板是一個更好的匹配。要調用複製構造函數,需要進行限定符轉換來綁定非常量左值f1const Foo&(必須添加const限定符)。

要調用構造模板,不需要轉換:T可以推斷到Foo&,其參考摺疊後(Foo& && - >Foo&),給出了參數x類型Foo&

您可以通過提供具有非const左值參考參數Foo&的第二個副本構造函數來解決此問題。

+1

還有一點點,就是參考摺疊(怎麼叫?),即'T &&&'=>'T&'因爲否則左值('f1')不能綁定到'T &&'。 –

4

只需提供精確匹配過載,即,一個與非constFoo&,除了傳統的拷貝構造。然後您可以通過明確的演員委託電話:

Foo(Foo& other) : Foo(static_cast<Foo const&>(other)) { }