Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do non-static data member initializers defeat uniform initialization syntax?

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?

like image 204
OldPeculier Avatar asked Jul 03 '13 20:07

OldPeculier


1 Answers

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.

like image 109
marack Avatar answered Sep 21 '22 10:09

marack