2

Consider this struct:

struct S { int index; };

It can be initialized using the braced-list like so:

S s{10}; //s::index becomes 10

However if I specify a default value for a member:

struct S { int index = -1; };

The braced-list initialization gives me a compiler error that it cannot convert initializer list to S. I suspect it might have to do with the default constructors being generated for the struct because I have specified the default value. But why cannot the initializer list override that?

The reason I want this is that I want to either initialize the struct with values or default it to some "invalid" default values. Because of this restriction I have to either specify a constructor myself or initialize the "invalid" defaults explicitly every time.

I am using VS2015 compiler.

Resurrection
  • 3,916
  • 2
  • 34
  • 56
  • Do you want a standards quote, confirmation that your compiler does indeed behave the way you tested it to behave, information about if/when this will change, or for us to find comprehensive documentation and recordings of all standarization meetings where this was decided by omission or commission? Or all of the above? I mean, "why: is a question, but it is a vague one. Please be specific, and ask a question on-topic and sufficiently narrow to be answered. – Yakk - Adam Nevraumont May 25 '16 at 20:31
  • @Yakk Please see the answers. The "why" is a valid question in this case because the code is well-formed. The problem is that this particular feature of C++14 (lifting the previous restriction, experienced and described in OP) has not yet been implemented in VS. So it is not my error, standard nor my omission to set any compiler flag etc. Since I did not know what exactly of the above was the issue I asked. – Resurrection May 25 '16 at 20:39
  • @Yakk I'm trying to find that great meta thread about asking "why" questions and I can't find it... gah... – Barry May 25 '16 at 20:45
  • 1
    @Barry: [This one?](http://meta.stackoverflow.com/q/323334/103167) – Ben Voigt May 25 '16 at 21:01
  • @BenVoigt Yes! thanks. – Barry May 25 '16 at 21:04
  • @Barry: 'twas the second hit searching meta for `[scope]`, which is the tag for discussions around the off-topic threshold. – Ben Voigt May 25 '16 at 21:22

1 Answers1

7

In C++11, an aggregate was defined in [dcl.init.aggr] as:

An aggregate is an array or a class (Clause 9) with no user-provided constructors (12.1), no brace-or-equal-initializers for non-static data members (9.2), no private or protected non-static data members (Clause 11), no base classes (Clause 10), and no virtual functions (10.3).

That has since been improved, as a result of N3605 to remove that condition (and has since then been reformatted to show those conditions as a bulleted list. Yay readability).

So as a result, in C++11, this:

struct S { int index = -1; };

int main() {
    S s{10};
}

is ill-formed because S doesn't qualify as an aggregate, so we don't attempt to do aggregate initialization, and there's no matching constructor for an int.

But as of C++14, S is an aggregate, so the code is well-formed. So either you're compiling in C++11 mode or VS2015 doesn't support C++14 aggregate initialization yet.

Barry
  • 286,269
  • 29
  • 621
  • 977
  • Actually it seems it is not a bug per se but rather shortcoming of MS in updating VS to C++14: http://en.cppreference.com/w/cpp/language/aggregate_initialization "No default member initializers (from C++11 until C++14)" – Resurrection May 25 '16 at 20:33
  • @Resurrection Ah, righto. One min. – Barry May 25 '16 at 20:34