2013-06-06 151 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

相关问题