Estou usando a Comunidade do Microsoft Visual Studio 2019, V16.5.2. Quero testar a inicialização da lista
Por favor, veja o seguinte programa de teste:
#include <string>
void foo(std::string str) {}
int main() {
foo( {"str1", "str2"} );
return 0;
}
Isso compila sem erro e aviso. Por quê?
Dá um erro de tempo de execução: Expression: Transposed pointer range
Alguém pode explicar o que está acontecendo aqui?
Editar.
Desmontei o código e o executei no depurador
foo( {"str1", "str2"} );
00F739A8 sub esp,1Ch
00F739AB mov esi,esp
00F739AD mov dword ptr [ebp-0C8h],esp
00F739B3 lea ecx,[ebp-0D1h]
00F739B9 call std::allocator<char>::allocator<char> (0F7136Bh)
00F739BE push eax
00F739BF push offset string "str2" (0F84DB8h)
00F739C4 push offset string "str1" (0F84E2Ch)
00F739C9 mov ecx,esi
00F739CB call std::basic_string<char,std::char_traits<char>,std::allocator<char> >::basic_string<char,std::char_traits<char>,std::allocator<char> ><char const *,0> (0F71569h)
00F739D0 call std::basic_string<char,std::char_traits<char>,std::allocator<char> >::basic_string<char,std::char_traits<char>,std::allocator<char> > (0F71843h)
00F739D5 add esp,1Ch
Falha na primeira chamada para o construtor?
Respostas:
std::string
possui um construtor de modelo que cria uma cadeia de caracteres a partir de um par de iterador de início / fim. Literais de string em C ++ são reduzidos paraconst char*
s. E ponteiros são iteradores. Portanto, a inicialização da lista escolheu o construtor de pares de início / fim.Você obteve um erro de tempo de execução porque os dois ponteiros não criam realmente um intervalo válido, que não pode ser determinado em tempo de compilação (geralmente).
fonte
<char const *,0>
. Alguém pode explicar isso?template< InputIt > (InputIt first, InputIt last,...)
construtor onde o parâmetro do modeloiter
éconst char*
.... e, aparentemente, sua implementação tem um segundo parâmetro inteiro por algum motivo?std::string
tem uma sobrecarga de construtor na forma dee isso é chamado porque
"str1"
e"str2"
decadência paraconst char*
's econst char*
é um tipo de iterador aceitável.Você sofre uma falha porque o "intervalo do iterador" que você passou para a função é inválido.
fonte
Que usam o construtor com iteradores de std :: string (6.).
Com [
InputIt
=const char*
].Então você tem UB, pois o intervalo
{"str1", "str2"}
é inválido.fonte