Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why copy constructor is not invoked?

Sorry for the overly ambiguous title.(due to the lack of my English skill). Please suggest a better title.

Please consider the following code.

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 failed to compile it with the error message error: no matching function for call to 'std::vector<double>::vector(A&)' : a(std::forward<Args>(args)...).

I cannot understand why this code is wrong. In my opinion, the compiler should invoke copy constructor in the line A b = a;.

However if I replace the constructor by the commented one(which simply takes values). It does compile. Furthermore, now the lines for default copy(and move) constructors are not needed. What happens here?

like image 942
Sungmin Avatar asked Jun 06 '13 02:06

Sungmin


2 Answers

In C++11 having the compiler automatically deduce template parameters (as you must do with a templated constructor) and applying && to the type creates a universal reference, which matches any type with any cv qualification, whether it's an lvalue or rvalue reference.

So in your case you're passing in an A, and therefore Args...=A &, Args &&...=A & &&, which is A & thanks to reference-collapsing rules, which is a better match than const A &, since the compiler doesn't have to add constness to a non-const variable.

like image 63
Robert Allan Hennigan Leahy Avatar answered Nov 18 '22 00:11

Robert Allan Hennigan Leahy


I think in this case the template constructor is a better match because it takes non-const value. if you change a to const it would call the copy constructor...

const A a(3,2);
A b = a;
like image 27
yngccc Avatar answered Nov 18 '22 00:11

yngccc