2013-06-06 185 views
10

抱歉,標題過於模糊(由於缺乏英語技能)。請建議一個更好的標題。爲什麼複製構造函數沒有被調用?

請考慮下面的代碼。

struct A { 
    typedef std::vector<double> State; 

    // template <class... Args> 
    // A(Args... args) 
    //  : a(args...) 
    // {} 

    template <class... Args> 
    A(Args&&... args) 
      : a(std::forward<Args>(args)...) 
    {} 

    A(const A&) = default; 
    A(A&&) = default; 

    State a; 
}; 

int main(){ 

    A a(3,2); 
    A b = a; // This line triggers an error!! 
} 

的gcc 4.8.0失敗,出現錯誤信息 error: no matching function for call to 'std::vector<double>::vector(A&)' : a(std::forward<Args>(args)...)編譯它。

我不明白爲什麼這段代碼是錯誤的。在我看來,編譯器應該調用行A b = a;中的拷貝構造函數。

但是,如果我通過註釋的(它只是取值)替換構造函數。它編譯。此外,現在不需要默認複製(和移動)構造函數的行。 這裏發生了什麼?

回答

9

在C++ 11編譯器來自動推斷模板參數(如你必須用一個模板構造函數做)和應用&&的類型創建一個通用引用,該引用可以匹配具有任何cv限定的任何類型,無論是左值還是右值引用。

所以你的情況你傳遞一個A,因此Args... = A &Args &&... = A & &&,這是A &感謝參考崩潰規則,這比const A &更好的匹配,因爲編譯器不必須將常量添加到非常量變量。

+1

哦,我明白了。感謝您的明確解釋。:) – Sungmin

3

我認爲在這種情況下模板構造函數是一個更好的匹配,因爲它採用非const值。如果你改變aconst它會調用拷貝構造函數...

const A a(3,2); 
A b = a; 
+0

謝謝如果我添加另一個拷貝構造函數'A(A&)= default'。它編譯好。 :) – Sungmin

相關問題