Код с codecvt не связывает [duplicate]

Много объяснений там, но сделать его еще проще. Возьмем, к примеру, List. Можно реализовать список с помощью:

  1. внутреннего массива
  2. Связанный список
  3. другая реализация

Построив интерфейс, скажем, List. Вы только указываете на определение списка или что означает List в действительности.

Вы можете использовать любой тип реализации, который внутренне говорит о реализации array. Но предположим, что вы хотите изменить реализацию по какой-то причине, скажем, ошибку или производительность. Затем вам просто нужно изменить объявление List<String> ls = new ArrayList<String>() на List<String> ls = new LinkedList<String>().

Нет, где еще в коде, вам придется что-то изменить; Потому что все остальное было построено на определении List.

26
задан user3443139 17 August 2015 в 16:29
поделиться

3 ответа

Старый вопрос, но для дальнейшего использования: это известная ошибка в Visual Studio 2015, как объясняется в последнем сообщении (7 января 2016 года) в этой теме MSDN Social.

Обходной путь для вашего примера выглядит следующим образом (я использовал свой метод как бесплатную функцию для простоты):

#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 условие будет нуждаться в уточнении. UPDATE: нет, не зафиксировано в VS 2017. Поэтому я обновил препроцессор условным до >= 1900 (изначально был == 1900).

26
ответ дан JPNotADragon 23 August 2018 в 01:25
поделиться
  • 1
    Ну, такой подход от разработчиков M $ удручает ... Представьте, что у вас есть тонны кода, который вам нужно переписать таким образом ... – Danatela 15 June 2016 в 10:56
  • 2
    Это сработало для меня. Как насчет противоположного направления? Если я делаю auto p = reinterpret_cast & lt; const char * & gt; (utf8_string.data ()); и convert.from_bytes (p) вместо этого, я получаю, что «нет подходящего пользовательского преобразования из« std :: basic_string »lt; int16_t, std :: char_traits & lt; int16_t & gt ;, std :: allocator & lt; int16_t & gt; & quot; & quot; к "std :: u16string" существует & Quot; – marc40000 2 June 2018 в 00:50

Другим возможным обходным путем является использование стандартного параметра второго шаблона (wchar_t) для wstring_convert. Он работает для обновления MS Visual Studio 2015 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 23 August 2018 в 01:25
поделиться

Определите недостающий символ в файле 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
5
ответ дан pascalx 23 August 2018 в 01:25
поделиться
  • 1
    VS2017: ошибка C2491: 'std :: codecvt & lt; char16_t, char, _Mbstatet & gt; :: id': определение члена статических данных dllimport не допускается – Bogdan 27 September 2017 в 20:51
  • 2
    В самом деле, он не компилируется с помощью / MD , потому что иностранная DLL не сможет узнать / использовать наше определение. Однако он работает с / MT . Так что это всего лишь половина обходного пути :-) – pascalx 27 September 2017 в 22:10
Другие вопросы по тегам:

Похожие вопросы: