为什么不调用复制构造函数?

时间:2013-06-06 02:19:57

标签: c++ c++11 default-copy-constructor

对于过于模糊的标题感到抱歉。(由于缺乏我的英语技能)。请建议一个更好的标题。

请考虑以下代码。

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;中调用复制构造函数。

但是,如果我用注释的构造函数替换构造函数(它只是取值)。它确实编译。此外,现在不需要默认复制(和移动)构造函数的行。 这里发生了什么?

2 个答案:

答案 0 :(得分:9)

在C ++ 11中,编译器自动推导出模板参数(正如你必须使用模板化构造函数)并将&&应用于该类型创建一个通用引用,它匹配任何具有任何cv限定的类型,它是左值或左值参考。

因此,在您的情况下,您传递A,因此Args... = A &Args &&... = A & &&,即{{1}感谢reference-collapsing规则,这是一个比A &更好的匹配,因为编译器不必将constness添加到非const变量。

答案 1 :(得分:3)

我认为在这种情况下,模板构造函数是一个更好的匹配,因为它采用非const值。如果您将a更改为const,则会调用复制构造函数...

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