Este código:
#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;
}
compila, mas retorna segfault. Por quê?
Testado no gcc 8.3.0 e em compiladores online.
std::pair
.Respostas:
std::initializer_list
não é para ser armazenado, é apenas para ... bem a inicialização. Internamente, apenas armazena um ponteiro para o primeiro elemento e o tamanho. No seu código, osstd::string
objetos são temporários e osinitializer_list
dois não se apropriam deles, nem prolongam a vida deles, nem os copiam (porque não é um contêiner), para que saiam do escopo imediatamente após a criação, mas vocêinitializer_list
ainda mantém um ponteiro para eles. É por isso que você recebe uma falha de segmentação.Para armazenar, você deve usar um contêiner, como
std::vector
oustd::array
.fonte
initializer_list
. Não é possível usar objetos somente para movimentação, portanto, não é possível usar o init da lista com o vetor unique_ptr, por exemplo. O tamanho deinitializer_list
não é uma constante em tempo de compilação. E o fato de questd::vector<int>(3)
estd::vector<int>{3}
fazer coisas completamente diferentes. Me deixa triste :(Gostaria apenas de adicionar um pouco mais de detalhes. Uma matriz subjacente de
std::initializer_list
comportamentos se comporta da mesma forma que os temporários. Considere a seguinte classe:e seu uso no seguinte código:
Imprime
desde que na primeira linha, uma instância temporária do tipo
X
é criada (convertendo o construtor de1
) e destruída também. A referência armazenadap
é então pendente.Quanto a
std::initializer_list
, se você usá-lo desta maneira:então, a matriz subjacente (temporária) existe enquanto
l
sair. Portanto, a saída é:No entanto, se você mudar para
A saída é novamente
já que a matriz (temporária) subjacente existe apenas na primeira linha. A desreferenciação do ponteiro para os elementos do
l
resultado resulta em um comportamento indefinido.A demonstração ao vivo está aqui .
fonte