Различные классы строк

Согласно ответу на этот вопрос std::wstring может быть либо u16string, либо u32string.

Согласно первому ответу на этот вопрос можно просто преобразовать на u16string и получить в результате std::wstring.

Что мне интересно, так это то, как я узнаю, есть ли у меня 16-битное или 32-битное представление? Если я хочу преобразовать UTF8 в std::wstring, похоже, я не могу использовать данное решение, потому что я не знаю, каково будет время выполнения.

Итак, как мне правильно преобразовать его? Или это не имеет значения, и преобразование всегда будет успешным в этом случае независимо от того, имею ли я 16-битное или 32-битное представление, ничего не теряя?

Может кто-нибудь уточнить?

РЕДАКТИРОВАТЬ:

Все это происходит из-за того, что здесь, на моем ноутбуке на базе Windows (Win8.1) с MSVC 2010, преобразование строки «abc» («abc») не выполняется со следующим кодом:

std::wstring_convert<std::codecvt_utf8<wchar_t> > myconv;
std::wstring table_name = myconv.from_bytes( (const char *) tableName );

Я еще не пробовал это на Linux/Mac, но, видя, что Windows дает сбой, говорит мне, что это нехороший знак, и я делаю что-то не так.


person Igor    schedule 28.05.2016    source источник
comment
std::wstring никогда не будет таким же, как u16string или u32string: типы символов wchar_t, char16_t и char32_t — это разные типы. Однако кодировка для std::wstring одинакова как для std::u16string, так и для std::u32string.   -  person Dietmar Kühl    schedule 28.05.2016
comment
Размер wchar_t составляет 16 бит в системе с 16-битным wchar_t, то есть в Windows. Количество битов в байте определяется CHAR_BIT из <limits.h>. Количество байтов на wchar_t определяется как sizeof(wchar_t).   -  person Cheers and hth. - Alf    schedule 28.05.2016
comment
@DietmarKühl, так что остается вопрос: как преобразовать utf-8 const char * в std::wstring без потери точности для каждой возможной комбинации?   -  person Igor    schedule 28.05.2016
comment
Стоит отметить, что широкие символы Windows (UTF-16) нестандартны по отношению к стандартам C и C++, и, наоборот, эти стандарты, гм, немного политизированы. Окна. Это означает, что, например. функции классификации символов в принципе не могут работать должным образом в Windows. Но на практике часть Unicode, не относящаяся к BMP, почти не используется; У меня сложилось впечатление, что это в основном старые китайские глифы.   -  person Cheers and hth. - Alf    schedule 28.05.2016
comment
@Cheersandhth.-Альф, хорошо. но тогда как правильно конвертировать?   -  person Igor    schedule 28.05.2016
comment
Что касается кодирования utf8 и преобразования в строковые типы, может помочь cppreference. Если вам нужна определенная кодировка (UTF16 или 32), используйте соответствующую std::uXXstring, а не std::wstring.   -  person coyotte508    schedule 28.05.2016
comment
@Igor: Вы можете выбрать во время компиляции правильное преобразование в зависимости от размера wchar_t.   -  person Cheers and hth. - Alf    schedule 28.05.2016
comment
@ coyotte508, я хочу преобразовать результат запроса SQLite в std::wstring. Поэтому он должен быть кроссплатформенным.   -  person Igor    schedule 28.05.2016
comment
Если у вас есть последовательность байтов и вы знаете ее кодировку, std::wstring_convert<std::codecvt<Char>, char, std::mbstate_t>, Char> кажется классом для преобразования в эту кодировку и из нее. Я не использовал это, хотя.   -  person Dietmar Kühl    schedule 28.05.2016
comment
Например, для переносимой обработки Unicode есть ICU. По крайней мере, поддержка Unicode в С++ отсутствует.   -  person Baum mit Augen    schedule 28.05.2016
comment
@Cheersandhth.-Альф, пожалуйста, посмотрите мою правку. Сначала я пытаюсь использовать Windows, и это не удается.   -  person Igor    schedule 28.05.2016
comment
@Igor Есть ли причина, почему именно std::wstring, а не просто std::u16string, который также является кроссплатформенным? Используют ли другие части кода std::wstring и также кодируют ли из utf8?   -  person coyotte508    schedule 28.05.2016
comment
@ coyotte508, да, все основано на wstring. Проблема в том, что SQLite — это библиотека C, которая работает с const char * как UTF-8. Кроме того, пожалуйста, смотрите мое редактирование.   -  person Igor    schedule 28.05.2016
comment
MSVC 2010 устарела. В частности, 2010 предшествует 2011. Используйте более новый компилятор.   -  person n. 1.8e9-where's-my-share m.    schedule 28.05.2016
comment
@ n.m., я получил его в своей школе, и это единственная доступная версия на базе Windows.   -  person Igor    schedule 28.05.2016
comment
Извините, у меня нет волшебного способа превратить MSVC2010 во что-то, что поддерживает стандарт языка C++ 2011 года. Вы можете бесплатно загрузить новый компилятор от Microsoft (инструмент командной строки, не уверен в IDE).   -  person n. 1.8e9-where's-my-share m.    schedule 28.05.2016
comment
@n.m., что ты имеешь в виду? MSVC 2010 отлично поддерживает C++11. Или вы имеете в виду, что это старый ЭЛТ? Кроме того, мой код выйдет из строя с более новым компилятором?   -  person Igor    schedule 28.05.2016
comment
Если ваш компилятор не может скомпилировать эти строки, он не поддерживает C++11.   -  person n. 1.8e9-where's-my-share m.    schedule 28.05.2016
comment
@n.m., компилируется, но выдает исключение   -  person Igor    schedule 28.05.2016
comment
@Igor: Обратите внимание на годы: 2010, 2011. Visual C++ 2010 не поддерживал C++11. Однако вы можете использовать Windows API для преобразования в Windows, и некоторые функции, которые, как я думаю, называются iconv в Unix-land, если вы хотите избежать зависимости от сторонней библиотеки. Функция Windows: MultiByteToWideChar< /а>.   -  person Cheers and hth. - Alf    schedule 28.05.2016
comment
Если у вас достаточно быстрое сетевое соединение, вы можете просто загрузить Visual Studio 2015 Community Edition, которая бесплатна для личного использования, и использовать функциональные возможности стандартной библиотеки C++11 (как предложил Дитмар).   -  person Cheers and hth. - Alf    schedule 28.05.2016
comment
но выдает исключение — значит, он по-прежнему не поддерживает C++11. У соответствующего компилятора не должно быть проблем с этим кодом.   -  person n. 1.8e9-where's-my-share m.    schedule 28.05.2016
comment
@Cheersandhth.-Alf Нельзя пренебрегать смайликом Pile of Poo, который на U+1F4A9 также находится за пределами BMP. (И вообще новые персонажи выходят за пределы BMP.)   -  person Alan Stokes    schedule 28.05.2016
comment
@n.m., я только что попытался запустить этот код в Linux с помощью gcc 5.2. Никаких исключений не было. Итак, я думаю, что копия MSVC, которая у меня есть, сломана.   -  person Igor    schedule 29.05.2016
comment
Что-то действительно сломано, потому что моя копия компилирует и запускает этот код нормально. Можешь показать всю программу?   -  person n. 1.8e9-where's-my-share m.    schedule 29.05.2016