While reading about different types of initialization, I stumbled upon one of the numerous weird interaction of std::initializer_list
(previous post here). It's apparently a simple topic, one of the first presented in C++ books when they present std::vector
.
The point is, if you have one constructor that takes a (I guess only) std::initializer_list
, when you brace initialize this constructor will be strongly prefered: in other words, std::vector<int> NewVect{5, 10}
will create an object containing 5 and 10, not 5 element initialized to 10 (std::vector<int> NewVect(5, 10)
).
A special behaviour takes place for auto
brace initialization (auto A={1,2,3}
will be deduced to be a std::initializer_list<int>
). Now, I can't believe in C++ a particular treatment is accorded to specific objects, since to my knowledge header are only well written and useful code snippet. Moreover, those syntaxes don't work if you don't directly or indirectly #include <initializer_list>
, even though my compiler, VS2017, prints a very special set of error pointing out that it needs that header to work (you can easily test this out with auto
).
So, my question is, given for granted that this behaviour is the effect of code from the initiliazer list's header and my compiler is probably built to assume the use of STD, how is it implemented? Could I reroute this behaviour to never happen aside from explicit call (that is, std::vector<int> NewVect{5, 10}
would be equivalent to std::vector<int> NewVect(5, 10)
and you would need now to call std::vector<int> NewVect{std::initializer_list<int>{5, 10}}
)? Would be possible to give this behaviour to other, user-built classes?
given for granted that this behaviour is the effect of code from the initiliazer list's header and my compiler is probably built to assume the use of STD, how is it implemented?
There is a special rule in the Standard that says something along the lines of: "if you are using list-initialization ({...}
) to construct an object, and the object has a constructor that takes std::initializer_list
, that constructor is chosen regardless of overload resolution". This means that std::initializer_list
constructors always have priority over others when using {...}
initialization syntax.
Could I reroute this behaviour to never happen aside from explicit call
In your classes, you can avoid using std::initializer_list
. Then this behavior will never occur. You cannot change this for std::
classes.
Would be possible to give this behaviour to other, user-built classes?
Not with your desired syntax, as std::initializer_list
is special. You can create your own initializer_list
alternative, or use something like a variadic template constructor to force users to have an explicit syntax.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With