Много объяснений там, но сделать его еще проще. Возьмем, к примеру, List
. Можно реализовать список с помощью:
Построив интерфейс, скажем, List
. Вы только указываете на определение списка или что означает List
в действительности.
Вы можете использовать любой тип реализации, который внутренне говорит о реализации array
. Но предположим, что вы хотите изменить реализацию по какой-то причине, скажем, ошибку или производительность. Затем вам просто нужно изменить объявление List<String> ls = new ArrayList<String>()
на List<String> ls = new LinkedList<String>()
.
Нет, где еще в коде, вам придется что-то изменить; Потому что все остальное было построено на определении List
.
Старый вопрос, но для дальнейшего использования: это известная ошибка в 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
).
Другим возможным обходным путем является использование стандартного параметра второго шаблона (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);
}
Определите недостающий символ в файле 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