Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Shouldn't this code compile according to 12.8p2 in the Standard?

This code doesn't compile in VS2010. It emits error C2440: 'argument' : cannot convert from 'A' to 'A &', but according to 12.8p2 in the Standard, A::A(A&) is a valid copy constructor and a is an lvalue in the expression A b = foo(a); in main().

#include <iostream>

class A
{
    public:

    int x;
    A(int a) { x = a; std::cout << "Constructor\n"; }
    A(A& other) { x = other.x; std::cout << "Copy ctor\n"; }
    A(A&& other) { x = other.x; other.x = 0; std::cout << "Move ctor\n"; }
};

A foo(A a) 
{
    return a;
}

int main(void)
{
    A a(5);
    A b = foo(a);
}
like image 492
Belloc Avatar asked Jun 23 '13 14:06

Belloc


1 Answers

I would say it depends on what standard you are talking about. Assuming C++11 then my take is that it should be OK and should produce the following result:

Constructor  <- Construction of 'a' in main
Copy ctor    <- Construction of 'a' in foo
Move ctor    <- Move from foo's return value into b

As you point out the a that gets passed into foo is an lvalue. However, the return value from foo is an rvalue and should therefore invoke either the const A& copy constructor (non-existent) in the pre C++11 case, or the move constructor in the C++11 case.

like image 159
Bishop Avatar answered Oct 21 '22 20:10

Bishop