Ce code:
#include <iostream>
#include <string>
std::pair<std::initializer_list<std::string>, int> groups{ { "A", "B" }, 0 };
int main()
{
for (const auto& i : groups.first)
{
std::cout << i << '\n';
}
return 0;
}
compile mais renvoie segfault. Pourquoi?
Testé sur gcc 8.3.0 et sur des compilateurs en ligne.
std::pair
.Réponses:
std::initializer_list
n'est pas destiné à être stocké, il est juste destiné à ... bien l'initialisation. En interne, il stocke juste un pointeur sur le premier élément et la taille. Dans votre code, lesstd::string
objets sont temporaires etinitializer_list
ni l'un ni l' autre ne les prend en charge, ne prolonge leur durée de vie, ni ne les copie (car ce n'est pas un conteneur) afin qu'ils sortent du champ d'application immédiatement après la création, mais votreinitializer_list
détient toujours un pointeur sur eux. C'est pourquoi vous obtenez un défaut de segmentation.Pour le stockage, vous devez utiliser un conteneur, comme
std::vector
oustd::array
.la source
initializer_list
. Il n'est pas possible d'utiliser des objets à déplacement uniquement, vous ne pouvez donc pas utiliser list init avec le vecteur de unique_ptr par exemple. La taille deinitializer_list
n'est pas une constante au moment de la compilation. Et le fait questd::vector<int>(3)
etstd::vector<int>{3}
faire des choses complètement différentes. Me rend triste :(Je voudrais juste ajouter un peu plus de détails. Un tableau sous-jacent de
std::initializer_list
se comporte de manière similaire aux temporaires. Considérez la classe suivante:et son utilisation dans le code suivant:
Il imprime
car à la première ligne, une instance temporaire de type
X
est créée (en convertissant le constructeur à partir de1
) et détruite également. La référence stockée dansp
est alors suspendue.Quant à
std::initializer_list
, si vous l'utilisez de cette façon:puis, le tableau sous-jacent (temporaire) existe tant qu'il existe
l
. Par conséquent, la sortie est:Cependant, si vous passez à
La sortie est à nouveau
puisque le tableau sous-jacent (temporaire) n'existe qu'à la première ligne. Déréférencer le pointeur sur les éléments de
l
entraîne alors un comportement indéfini.La démo en direct est ici .
la source