mardi 30 octobre 2018

initializer_list, constructors and braced initialization

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?

Aucun commentaire:

Enregistrer un commentaire