Kan Li
Kan Li

Reputation: 8797

How to make initializer list and class member initializer work together?

The following code neither compiles with -std=c++11 under gcc-4.7.1 nor clang-3.2. So I think I did something wrong. But I don't know why. Can someone give me a hint? Basically if I remove the in-class member initializer for X, it works. So why doesn't initializer list work with in-class member initializer?

struct X {
    int x = 1;
    int y = 1;
};

int main() {
    X x = {1, 2};
}

gcc compile error:

a.cpp: In function 'int main()':
a.cpp:7:16: error: could not convert '{1, 2}' from '<brace-enclosed initializer list>' to 'X'

Upvotes: 9

Views: 413

Answers (1)

juanchopanza
juanchopanza

Reputation: 227370

By having the initialization of non-static data members at the point of declaration, your class is no longer an aggregate (see 8.5.1 Aggregates [decl.init.aggr]).

A workaround is to add a two-parameter constructor. This allows you to use initializer-list initialization, which allows same syntax as aggregate initialization, even if your class is not technically an aggregate.

struct X {
  X(int x, int y) : x(x), y(y) {}
    int x = 1;
    int y = 1;
};

int main() 
{
    X x1{1, 2};
    X x2 = {1,2};
}

Note: These rules have been relaxed for C++1y, meaning your type would indeed be an aggregate.

Upvotes: 13

Related Questions