I have the following code:
struct X
{
int a, b;
};
class Y
{
public:
Y(const X& x) : x_{x} {}; // C2797 error
private:
X x_;
};
Compiled with MSVC2013 Update 3, it complains about a C2797 error. If I replace the curly braces with parantheses (i.e. x_(x)
) the program compiles successfully.
Why does this happen? Is this compiler behaviour C++11-compliant? What about C++14?
Edit: To be more clear, I am not sure if x_{x}
above should, according to the standard, call X(std::initializer_list)
or if it's a valid syntax for calling X(const X&)
. As far as I know, it is the latter. Am I right?
From the standard:
— If T is an aggregate, aggregate initialization is performed.
[...]
— Otherwise, if T is a class type, constructors are considered. The applicable constructors are enumerated and the best one is chosen through overload resolution (13.3, 13.3.1.7). If a narrowing conversion (see below) is required to convert any of the arguments, the program is ill-formed.
In the context above, x_{x}
will not call the copy constructor, because X
is an aggregate. It will attempt aggregate initialization, which:
In MSVC, is not implemented. MSVC also seems to fail compilation when X
is std::string
, which is not an aggregate, so it may have some C++11 compliance issues.
In gcc, it is implemented, but the program is ill-formed and cannot compile (attempting to initialize an aggregate expecting {int, int}
from a {const X}
.