Estoy usando Microsoft Visual Studio Community 2019, V16.5.2. Quiero probar la inicialización de la lista
Consulte el siguiente programa de prueba:
#include <string>
void foo(std::string str) {}
int main() {
    foo( {"str1", "str2"} );
    return 0;
}
Esto compila sin error y advertencia. ¿Por qué?
Da un error de tiempo de ejecución: Expression: Transposed pointer range
¿Alguien puede explicar qué está pasando aquí?
Editar.
Desmonté el código y lo ejecuté en el 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  
Se bloquea en la primera llamada al constructor?

Respuestas:
std::stringtiene un constructor de plantillas que construye una cadena a partir de un par de iteradores de inicio / fin. Los literales de cadena en C ++ se convierten enconst char*s. Y los punteros son iteradores. Por lo tanto, la inicialización de la lista eligió el constructor de pares de inicio / fin.Recibió un error de tiempo de ejecución porque los dos punteros en realidad no crean un rango válido, que no se puede determinar en tiempo de compilación (generalmente).
fuente
<char const *,0>. ¿Alguien puede explicar esto?template< InputIt > (InputIt first, InputIt last,...)constructora donde el parámetro de plantillaiteresconst char*.... y al parecer su aplicación tiene un segundo parámetro entero por alguna razón?std::stringtiene una sobrecarga del constructor en forma dey esto se llama porque
"str1"y"str2"decae aconst char*'s yconst char*es un tipo de iterador aceptable.Se bloquea porque el "rango de iterador" que pasó a la función no es válido.
fuente
Que utilizan el constructor con iteradores de std :: string (6.).
Con [
InputIt=const char*].Entonces tienes UB ya que el rango
{"str1", "str2"}no es válido.fuente