Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c++

c++11

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'
like image 516
Kan Li Avatar asked Jan 29 '13 08:01

Kan Li


1 Answers

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.

like image 190
juanchopanza Avatar answered Nov 09 '22 00:11

juanchopanza