usar resueltos leer funciones ejercicios ejemplos como caracteres cadenas cadena arreglo c++ visual-c++ implicit explicit

c++ - resueltos - ¿Por qué el compilador elige bool sobre string para typecast implícito de L ""?



leer cadena de caracteres en c (5)

Habiendo introducido recientemente una sobrecarga de un método, la aplicación comenzó a fallar. Finalmente rastreando, se llama al nuevo método donde no esperaba que fuera.

Tuvimos

setValue( const std::wstring& name, const std::wstring& value ); std::wstring avalue( func() ); setValue( L"string", avalue ); std::wstring bvalue( func2() ? L"true", L"false" ); setValue( L"bool", bvalue ); setValue( L"empty", L"" );

Se modificó para que cuando se almacena un valor bool usemos las mismas cadenas (almacenamiento interno de datos de cadenas)

setValue( const std::wstring& name, const std::wstring& value ); setValue( const std::wstring& name, const bool& value ); std::wstring avalue( func() ); setValue( L"string", avalue ); setValue( L"bool", func2() ); setValue( L"empty", L"" ); << --- this FAILS!?!

El problema con L "" es que está lanzando implícitamente y anteriormente estaba contento de ser un std :: wstring, pero no prefiere ser un bool. El compilador de MSVC no se queja, o genera una advertencia, así que me preocupa que incluso si "arreglo" el setValue (L "empty", L ""); ser

setValue( L"empty", std::wstring() );

alguien más puede venir más tarde y simplemente usar setValue (L "vacío", L ""); y tenemos que seguir este problema de nuevo.

Pensamos usar explícito en el método, pero no es una palabra clave válida para este uso. ¿Hay alguna forma de hacer que el compilador se queje de esto o evitar el problema? De lo contrario, estoy pensando en cambiar el nombre del método que toma un bool para asegurarse de que no puede hacer una suposición incorrecta.


Como bool es un tipo incorporado, se prefiere la conversión de wchar_t a bool. Yo diría que la solución más simple es agregar una sobrecarga que tome una matriz wchar_t y emitir explícitamente allí:

setValue( const std::wstring& name, const wchar_t s[] ) { setValue(name, wstring(s)); }


L "" es un puntero a una cadena de caracteres anchos. El compilador cree que la conversión a bool tiene prioridad sobre una conversión a std :: wstring.

Para solucionar el problema, introduce un nuevo setValue:

void setValue(std::wstring const& name, const wchar_t * value);


Para simplificar un poco, el siguiente código

#include <iostream> using namespace std; void f(const string &s) { cout << "string version called" << endl; } void f(const bool &b) { cout << "bool version called" << endl; } int main() { f("Hello World"); }

imprime "versión bool llamada". ¿Estás seguro de que tu código falla solo con la cadena vacía?


Podrías hacer que la nueva función tome otro tipo de bool, tal vez solo un proxy para bool, que no es convertible desde una cadena literal. Pero realmente cambiaría el nombre de la función de toma de booleos y terminaría con eso.


Primero, la causa de este problema: C ++ Standard 13.3.3.2 define un orden para las secuencias de conversión. Dice que una secuencia de conversión definida por el usuario es peor que una secuencia de conversión estándar. Lo que ocurre en su caso es que el literal de la cadena se somete a una conversión booleana (definida en 4.12 . Esta es una conversión estándar). No utiliza la conversión definida por el usuario a std::wstring que sería necesaria si tomara la otra sobrecarga.

Yo recomendaría simplemente cambiar el nombre de una de las sobrecargas o agregar una sobrecarga que acepte directamente la cadena literal (usando el tipo de parámetro wchar_t const* ).