10

In C++11 it's possible to initialize an struct using uniform initialization like below:

struct BasicStruct {
    BasicStruct (int x, double y) : x_{x}, y_{y} {}

private:
    int x_;
    double y_;
};

BasicStruct var1{5, 3.2};

Questions:

  1. When should I use this syntax BasicStruct var1{5, 3.2} instead of calling the constructor like BasicStruct var1(5, 3.2)?

  2. When should I initialize an attribute like x_{x} instead of old fashion way x_(x)?

MBZ
  • 26,084
  • 47
  • 114
  • 191

1 Answers1

8

Use list-initialization when the list is generic and you could substitute another container, such as an array, an aggregate, or a vector, without changing its meaning much.

// "triplet" may be a struct, an array, or a std::vector,
// but it has at least single-precision floating-point values.
triplet dimensions { 5, 1.2f, static_cast< float >( M_PI ) };

If you are constructing a specific class with arguments to a specific constructor, then old-fashioned parens are more appropriate.

One unique feature of initialization with a braced-init-list is that it does not allow narrowing conversions which could cause numeric data to be lost, for example the fractional part of a floating-point number or the high bits of a long. This helps to flag (or prevent) errors resulting from substitution of e.g. a narrower array type during code refactoring.

Likewise, the other case where x{ y } is appropriate is when performing a numeric conversion that you do not with to be lossy. x( y ) will try really hard to make the conversion, even resorting to a reinterpret_cast, and should generally be avoided.

The terminology "uniform initialization" is a bit optimistic, and it does not appear in the standard. It is not appropriate for all cases. Braces generally indicate lists, so it's properly called list-initialization. And that is when it should be used.

Potatoswatter
  • 134,909
  • 25
  • 265
  • 421