web-dev-qa-db-ja.com

Visual Studio C ++ 2015 std :: codecvtとchar16_tまたはchar32_t

このコードはVS2013で問題なくコンパイルされました。

std::string Unicode::utf16_to_utf8(std::u16string utf16_string)
{
    std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert;
    return convert.to_bytes(utf16_string);
}

今VS2015で私は得ます:

1>unicode.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: static class std::locale::id std::codecvt<char16_t,char,struct _Mbstatet>::id" (__imp_?id@?$codecvt@_SDU_Mbstatet@@@std@@2V0locale@2@A)
32
user3443139

古い質問ですが、将来の参考のために、これはVisual Studio 2015の既知のバグです。これは、MSDN Socialの this thread の最新の投稿(2016年1月7日)で説明されています。

あなたの例の回避策は次のようになります(私は簡単にするためにあなたのメソッドをフリー関数として実装しました):

#include <codecvt>
#include <locale>
#include <string>
#include <iostream>

#if _MSC_VER >= 1900

std::string utf16_to_utf8(std::u16string utf16_string)
{
    std::wstring_convert<std::codecvt_utf8_utf16<int16_t>, int16_t> convert;
    auto p = reinterpret_cast<const int16_t *>(utf16_string.data());
    return convert.to_bytes(p, p + utf16_string.size());
}

#else

std::string utf16_to_utf8(std::u16string utf16_string)
{
    std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert;
    return convert.to_bytes(utf16_string);
}

#endif

int main()
{
    std::cout << utf16_to_utf8(u"Élémentaire, mon cher Watson!") << std::endl;

    return 0;
}

うまくいけば、問題は将来のリリースで修正されるでしょう。そうでなければ、#if条件を調整する必要があります。更新:いいえ、VS 2017では修正されていません。そのため、条件付きでプリプロセッサを>= 1900に更新しました(最初は== 1900でした)。

28
JPNotADragon

欠落しているシンボルをcppファイルに定義します。

// Apparently Microsoft forgot to define a symbol for codecvt.
// Works with /MT only
#include <locale>

#if (!_DLL) && (_MSC_VER >= 1900 /* VS 2015*/) && (_MSC_VER <= 1911 /* VS 2017 */)
std::locale::id std::codecvt<char16_t, char, _Mbstatet>::id;
#endif
7
pascalx

これはVS2017で私のために働きました:

std::wstring utf8_to_utf16(std::string utf8_string)
{
   return std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t>{}.from_bytes(utf8_string);
}

std::string utf16_to_utf8(std::wstring utf16_string)
{
    return std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t>{}.to_bytes(utf16_string);
}
4
Paul Williams

別の可能な回避策は、wstring_convertにデフォルトの2番目のテンプレートパラメーター(wchar_t)を使用することです。 「MS Visual Studio 2015 update 3」で動作しています。 プラットフォームに依存しないソリューションであることに注意してください。 Windowsのみ。

std::string utf16_to_utf8(std::u16string u16_string)
{
    std::wstring wide_string(u16_string.begin(), u16_string.end());
    std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> convert;
    return convert.to_bytes(wide_string);
}
3
aleksandrm8