Отключить предупреждение в MSVС++ 2010
У меня есть следующий код:
/** Stupidly copies unicode chars into normal chars. */
std::string wstring2string(__in const std::wstring& s)
{
std::string temp(s.length(), ' ');
#pragma warning(push)
#pragma warning(disable: 4244) // possible loss of data
std::copy(s.begin(), s.end(), temp.begin());
#pragma warning(pop)
return temp;
}
Мой компилятор все еще показывает мне предупреждение C4244:
1>c:\program files\microsoft visual studio 10.0\vc\include\xutility(2144): warning C4244: '=': Konvertierung von 'const wchar_t' in 'char', möglicher Datenverlust
1> c:\program files\microsoft visual studio 10.0\vc\include\xutility(2165): Siehe Verweis auf die Instanziierung der gerade kompilierten Funktions-template "_OutIt std::_Copy_impl<_InIt,_OutIt>(_InIt,_InIt,_OutIt,std::_Nonscalar_ptr_iterator_tag)".
(на английском языке: "Преобразование const wchar_t
в char
, возможная потеря данных, см. ссылку на экземпляр только что скомпилированного шаблона функции..." ).
Как я могу отключить его?!
Ответы
Ответ 1
Чтобы избавиться от этого предупреждения, вам нужно добавить #pragma warning...
вокруг вашего заголовочного файла, который включает эту функцию. В вашем случае это бесполезность. Который включен несколькими другими файлами. Так будет трудно найти. Но вы можете попробовать это так.
#pragma warning(push)
#pragma warning(disable: 4244) // possible loss of data
#include <xutility>
#pragma warning(pop)
Your includes go here...
std::string wstring2string(__in const std::wstring& s)
{
std::string temp(s.length(), ' ');
std::copy(s.begin(), s.end(), temp.begin());
return temp;
}
Кроме того, я бы рекомендовал правильное преобразование. Посмотрите ICU, или, по крайней мере, используйте функцию из стандарта. Например. mbstowcs
Ответ 2
Когда я хочу это сделать, я просто положил предупреждение #pragma (disable, 2422) в верхнюю часть файла .cpp., после # include. Но если бы я был вами, я бы попытался решить предупреждение, а не подметать его под ковром. Устранение константы может привести к поведению undefined.
Чтобы решить проблему, попробуйте что-то вроде этого (мы используем эту функцию в нашем решении):
string wtoString( const wchar_t *ws ){
size_t bufferSize = (wcslen(ws) + 1) * sizeof(wchar_t);
char * buffer = new char[ bufferSize ];
size_t convertedChars;
wcstombs_s( &convertedChars, buffer, bufferSize, ws, _TRUNCATE);
string result(buffer);
delete[] buffer;
return result;
}
Адаптируйте его для получения const wstring &, это должно быть легко, учитывая, что когда вы вызываете c_str() для wstring(), вы получаете const wchar_t *
EDIT. Теперь, когда я снова посмотрю на это, его можно улучшить, если вы используете RAII для локальной переменной буфера. На всякий случай.
EDIT: исправленный код для рассмотрения размера символа
Ответ 3
Попробуйте изменить свою функцию на что-то вроде этого (нет компилятора С++, доступного для проверки его компиляции):
std::string wstring2string(__in const std::wstring& s)
{
size_t bufferSize;
// first call to wcstombs_s to get the target buffer size
wcstombs_s(&bufferSize, NULL, 0, ws.c_str(), ws.size());
// create target buffer with required size
char* buffer = new char[bufferSize];
// second call to do the actual conversion
wcstombs_s(&bufferSize, s.c_str(), bufferSize, ws.c_str(), ws.size());
string result(buffer, bufferSize);
delete[] buffer;
return result;
}
(Вдохновленный ответом dario_ramos)
Как и в Windows, вы даже можете использовать функцию Windows API WideCharToMultiByte, которая в основном делает то же самое, но позволяет указать целевую кодировку.
Ответ 4
Предупреждение не отображается, только если оно отключено, прежде чем включать строковый h файл. Размышляя о причине такого поведения, я думаю, что это проблема с шаблоном. Когда класс шаблона включен, компилятор делает вид предварительной компиляции. Полная компиляция выполняется только при создании экземпляра шаблона. Похоже, что компилятор VС++ сохраняет настройки предупреждений с этапа предварительной компиляции и меняет их до создания экземпляра.