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;

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

4

2 回答 2

9

在 C++11 中,让编译器自动推导出模板参数(就像您必须使用模板化构造函数一样)并应用于&&该类型会创建一个通用引用,该引用匹配具有任何 cv 限定的任何类型,无论是左值还是右值引用。

因此,在您的情况下,您传递了一个A,因此Args...= A &Args &&...= A & &&,这要A &归功于引用折叠规则,这是比 更好的匹配const A &,因为编译器不必将 const 性添加到非常量变量。

于 2013-06-06T02:36:46.673 回答
3

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

const A a(3,2);
A b = a;
于 2013-06-06T02:33:33.970 回答