una resueltos programacion orientada objetos miembros metodos ejercicios ejemplos codigo clases clase c++ string c++11 constructor

resueltos - Diferencia entre los métodos de construcción de objetos C++



objetos en c++ (2)

Con C++ 14 o C++17 o C++11 , este comportamiento indefinido resulta en un error de compilación tanto en clang5.0 como en gcc7.2 .

#include<string> std::string S(''/0'');

error: no hay función coincidente para la llamada a ''std :: __ cxx11 :: basic_string :: basic_string (char)'' std :: string S (''/ 0''); ^

La UB se corrige (para dar un error de compilación) en las versiones recientes del compilador.

Las diferentes sintaxis de construcción en C ++ siempre me han confundido un poco. En otra pregunta , se sugirió intentar inicializar una cadena como tal

std::string foo{ ''/0'' };

Esto funciona y produce el resultado deseado: una cadena de longitud 1 que contiene solo el carácter nulo. Al probar el código, accidentalmente escribí

std::string foo(''/0'');

Esto compila bien (sin advertencias incluso con -Wall ), pero termina en tiempo de ejecución con

terminate called after throwing an instance of ''std::logic_error'' what(): basic_string::_M_construct null not valid Aborted (core dumped)

Ahora, por lo que puedo decir, no hay un constructor para std::string que tome un solo carácter como argumento, y esta hipótesis se confirma aún más cuando intento pasar el carácter indirectamente.

char b = ''/0''; std::string a(b);

Esto produce un error de compilación largo y agradable. Como hace esto

std::string a(''z'');

Así que mi pregunta es: qué permite std::string a(''/0''); para compilar, y qué lo hace diferente de std::string a{ ''/0'' }; ?

Nota al pie: Compilar usando g++ en Ubuntu. Esto no me parece un error de compilación, pero por si acaso ...


El carácter ''/0'' se puede convertir implícitamente a un valor entero de 0 lo que representa una constante de puntero nula definida por la implementación . Esta:

std::string foo(''/0'');

llama a una sobrecarga del constructor que acepta un puntero de tipo const char* como parámetro y da como resultado un comportamiento indefinido. Es equivalente a pasar 0 o NULL :

std::string foo(0); // UB std::string bar(NULL); // UB

La referencia para las sobrecargas de constructores 4 y 5 dice:

El comportamiento no está definido si s ... incluido el caso cuando s es un puntero nulo .

La segunda afirmación:

std::string foo{''/0''}; // OK

llama a un constructor que acepta std::initializer_list<char> como parámetro y no causa UB.

En su lugar, puede llamar al número de conteo de caracteres de la sobrecarga del constructor:

std::string s(1, ''/0'');