6

If all of your class/struct data members lack initializers, you can use uniform initialization syntax to construct the object.

struct foo
{
    int i;
    float f;
};
...
foo bar{ 5, 3.141f };

But if one or more members have initializers, uniform initialization syntax becomes invalid.

struct foo
{
    int i;
    float f = 0;
};
...
foo bar{ 5, 3.141f };  // Compiler error.

I surmise that the addition of a data member initializer automatically implements one or more default constructors and suppresses the default implementation of the initialization_list constructor. Is that the intended standard? Why does it work this way?

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524
OldPeculier
  • 11,049
  • 13
  • 50
  • 76
  • 8
    There is no "default implementation of the `initializer_list` constructor". What you have in the first snippet is called *aggregate initialization*. – Xeo Jul 03 '13 at 20:33
  • 1
    To complement @Xeo's comment, see *8.5.1 [dcl.init.aggr]* and *8.5.4 [dcl.init.list]*. – syam Jul 03 '13 at 20:44
  • 1
    Relevant: http://stackoverflow.com/questions/4178175/what-are-aggregates-and-pods-and-how-why-are-they-special/7189821#7189821 – R. Martinho Fernandes Jul 04 '13 at 11:20

1 Answers1

2

Yes, this is intended by the standard. What you are attempting here is aggregate initialization. Unfortunately, your second foo is no longer considered an aggregate due to the equal initializer of f. See 8.5.1 [dcl.init.aggr] (emphasis mine):

An aggregate is an array or a class (Clause 9) with no user-provided constructors (12.1), no brace-or-equalinitializers 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).

Because you have an equal initializer for the member f, you will need to provide a custom constructor to support the syntax you are after:

struct foo
{
  int i;
  float f = 0;
  constexpr foo(int i, float f) : i(i), f(f) { }
};
...
foo bar{ 5, 3.141f }; // now okay

As to why this was specified in the standard, I have no idea.

marack
  • 2,024
  • 22
  • 31
  • 1
    Note that it's under consideration for the next standard to allow aggregate init even with non-static data member initializers. – Xeo Oct 08 '13 at 23:00