Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should I use list initialization in a constructor initializer list?

In GotW #6b part 2, we find the code

class polygon {
public:
    polygon() : area{-1} {}
    //....
    double area;
};

Why should we use list initialization for base types instead of the commonly used area(-1)? Are there any advantages / situations where they behave differently?

like image 570
Luchian Grigore Avatar asked Jan 13 '23 07:01

Luchian Grigore


2 Answers

Why should we use list initialization for base types instead of the commonly used area(-1)?

First of all, I think the message there is just that C++11's uniform initialization should be used whenever it can be used. In this case, it is mostly a matter of style and taste.

Whether the style and taste promoted by the author will become a de facto standard is hard to tell at this time. We all know uniform initialization is not that uniform after all. On the other hand, in most situations the benefits of adopting it as the default coding style are appealing - syntactic uniformity, plus the fact that problems such as the Most Vexing Parse disappear.

This said, when the initializer list contains only one element, the initialized object is initialized from that element (§ 8.5.4/3). This makes the initialization in your example equivalent to regular direct-initialization (except that narrowing conversions are not allowed).

In other words, area{-1} and area(-1) in your example are both direct initializations and they are equivalent. Choosing one over the other is just a matter of style.

Are there any advantages / situations where they behave differently?

As mentioned above, one situation where they behave differently is given by initializations that involve narrowing conversions. For instance, while this is allowed:

int x{42};

This is not:

int y{3.14}; // ERROR! Narrowing conversion
like image 166
Andy Prowl Avatar answered Jan 21 '23 10:01

Andy Prowl


This wouldn't make a difference for scalars, but the author was probably conforming to the new syntax. For example, before C++11 you couldn't initialize arrays through the initializer list, but this can be accommodated easily through aggregate-initialization:

struct A
{
    A() : data{1, 2, 3} // this wouldn't work as 'data(1, 2, 3)'
    {}

    int data[3];
};

Similarly, you would do likewise for vectors.

like image 42
David G Avatar answered Jan 21 '23 09:01

David G