2010-12-03 22 views
6

Esto funciona con std :: string¿Cómo agrego un wstring?

std::string class::something(char* input) { 
    std::string s(input); 
    s = "hai! " + s; 
    return s; 
} 

pero no si lo intento lo mismo con wstring

std::wstring class::something(wchar_t* input) { 
    std::wstring s(input); 
    s = "hai! " + s; 
    return s; 
} 

¿Cómo puedo hacer lo mismo con std :: wstring?

Respuesta

13

El problema aquí es tipos. Un wstring no es una cadena, pero una constante de cadena entre comillas se relaciona con ella (por lo general es un const char*), por lo

s = "hai! " + s; 

es en realidad un problema.

El valor "hai! " es del tipo const char*, no el tipo const wchar_t*. Como const char* es un tipo básico, está buscando un operator+ global que opere const char* y wstring, que no existe. Encontraría uno para const wchar_t* y wstring, porque std::basic_string<T>, the template underyling type for both string and wstring (usando char y wchar_t como parámetro de tipo, respectivamente) también crea métodos de plantilla para operator+ (const T*& s1, const basic_string<T> s2) para que la adición pueda funcionar.

Por lo tanto, es necesario hacer una wstring "Hai!":

std::wstring class::something(wchar_t* input){ 
    std::wstring s(input); 
    s = L"hai! " + s; 
    return s; 
} 

El L prefijo en una constante de cadena, en Visual C++, define que sea "larga", y por lo tanto un wstring. wstringis actually basic_string<wchar_t>, que es, debido al comportamiento de las plantillas C++, un tipo completamente diferente de basic_string<char> (a std::string), por lo que no puede combinar los dos.

+0

"El valor" hai! "es de tipo std :: string ..." es una afirmación incorrecta. El tipo real es 'char const *'. "El prefijo L en una constante de cadena, en Visual C++, lo define como" largo "y, por lo tanto, un wstring" también es incorrecto de tres maneras. Primero, no es específico de VC++. Segundo, lo define como "ancho", no "largo". En tercer lugar, no es un wstring, es un 'wchar_t const *'. –

+0

Bastante correcto. Me di cuenta de esto mientras escribías el comentario y editabas mi respuesta al mismo tiempo. Aunque pensé que era una const wchar_t const *, no solo una wchar_t const *? Que inexactamente escribí como const wchar_t *, faltando el segundo const, pero no estoy seguro de querer editarlo nuevamente para corregir eso, ahora que estoy equivocado en lugar de estar flagrantemente equivocado. –

7

Se usa un literal de caracteres anchos en lugar de un carácter de carácter literal con el prefijo "hai!" con L.

-1

En lugar de tener 2 versiones del código (1 de ancho y 1 para varios bytes):

#ifdef _UNICODE 
    typedef std::wstring tstring; 
    typedef wchar_t tchar; 
# define TEXT(s) L##s 
#else 
    typedef std::string tstring; 
    typedef char tchar; 
# define TEXT(s) s 
#endif 

tstring class::something(tchar* input) 
{ 
    tstring s(input); 
    s = TEXT("hai! ") + s; 
    return s; 
} 

Esto evita tener que volver a escribir el código cuando se cambia la cadena de codificación compilador opciones del compilador.

+0

'typedef std :: wstream tstring;' wstream debe ser wstring, ¿o no? Además, no se recomienda agregar otra Macro para cadenas: en VS TEXT ya existe, por lo que incluso se generaría una advertencia de compilación si se usan bibliotecas comunes como ATL/MFC en el proyecto (o se agregan más adelante). Prefiero recomendar una función de plantilla. – Alex

Cuestiones relacionadas