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::string
tiene 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 plantillaiter
esconst char*
.... y al parecer su aplicación tiene un segundo parámetro entero por alguna razón?std::string
tiene 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