Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are the pros and cons of each way to initialize an expression?

Tags:

c++

c++11

c++14

This is inspired from a post by Andrei Alexandrescu.

What are the pro's and con's of initializing an expression with the following methods? When should I prefer one over the other?

auto v = expr;
T v = expr;
auto v(expr);
T v(expr);
auto v { expr }; 
T v {expr};
like image 976
pyCthon Avatar asked Sep 10 '13 23:09

pyCthon


1 Answers

auto v = expr;
auto v(expr);

When in your code either you don't know the type of expr and want to stay generic, or in your code it is absolutely clear what type expr has (definition right at the line above, etc), so that the auto will not add confusion.

The form of the initialization, parens or not, is irrelevant (only relevant to language lawyers, as there are subtle differences). Use what you feel more comfortable with.


T v = expr;
T v(expr);

If in your code it is not clear what expr is (definition too far apart, etc..), or if you don't know the type of expr but want v to be of the type T. Use the first form if you want to keep working with the "kind of value" that "expr" has (i.e if expr is a string and T is of a string type). If you build up a whole new kind of value (i.e a Widget, and expr is the widget's color), use the second form.


auto v { expr }; 

Never use this in current C++ (and probably within the next few years). It will declare v to be an std::initializer_list<TypeOfExpr>. If you want that, use the type directly and write it out. It is way too subtle (and there are proposals for beyond-C++14 to change this fact, so there is hope that you can write this in C++17 or something like that).


T v {expr};

If you want to protect yourself from narrowing conversions (i.e going from 1000 to char accidentally), or if you want to initialize a class that has an initializer list constructor, or if you have an aggregate the member(s) of which you want to initialize, use this form. Alternatively, you may use the following if you are dealing with an initializer list constructor, an aggregate or simple non-class type

T v = { expr };

I would not use it for calling an arbitrary constructor. I would use the following form for that

T v(expr);

However, there are people who prefer to use the braces form for that too. I like to know for sure what my code is doing, hence when I want to call a constructor, and don't want to randomly do an aggregate or list initialization constructor call instead, I use parens instead of braces. 

like image 127
Johannes Schaub - litb Avatar answered Oct 25 '22 15:10

Johannes Schaub - litb