Search code examples
c++c++11visual-studio-2013initializationuniform-initialization

Why do I get error C2797 in this example?


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?


Solution

  • 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}.