La présentation de "Le cauchemar de l'initialisation en C++" de Nicolai Josuttis à CppCon 2018 avait, à un moment donné, le code suivant:
std::vector< std::string > v07 = {{ "1", "2" }};
Nicolai dit ce qui suit (transcription mienne):
Le problème est que ce qui se passe ici est que nous interprétons ces deux paramètres comme itérateurs . Ce sont donc des itérateurs, donc ceci est le début de la plage, et ceci est la fin de la plage, et ils doivent faire référence à la même plage de caractères ; parce que les caractères se convertissent implicitement en chaînes, cela se compilera. Si vous êtes chanceux, vous obtiendrez un coredump. Sinon, vous avez un gros problème.
Il m'a perdu là-bas. Quelqu'un peut-il expliquer ce qui se passe ici, exactement, étape par étape?
Ci-dessous le code
std::vector< std::string > v07 = { { "1", "2" } };
est équivalent à
std::string s = {"1","2"}; // call string(const char*, const char*)
std::vector<std::string> v07 = {s}; // initializer list with one item
le problème est avec
s={"1","2"};
Cela appelle string(const char* start, const char* end)
constructeur, mais start
et end
doivent faire référence au même objet chaîne. "1" et "2" sont deux objets différents, donc cela mène à UB.