OP, dużo by pisać. Jest to puszka pandory i jedna z tych rzeczy, której do tej pory komitetowi standaryzacyjnemu nie udało się ogarnąć do końca.
Zachęcam do sprawdzenia wyniku tego programu:
Kopiuj
#include <iostream>
#include <string>
#include <locale>
#include <codecvt>
using namespace std;
template <typename O, typename S>
void write_hex(O &out, const S &s) {
for (auto x : s) {
out << std::hex << static_cast<uint16_t>(x) << " ";
}
out << endl;
}
int main() {
wstring_convert<codecvt_utf8<char16_t>, char16_t> cvu16;
wstring_convert<codecvt_utf8<wchar_t>> cvu32;
cout << "string:" << endl;
string str = u8"abecą";
cout << str << endl;
write_hex(cout, str);
cout << endl;
cout << "u16string:" << endl;
u16string str_u16 = u"abecą";
cout << cvu16.to_bytes(str_u16) << endl;
write_hex(cout, str_u16);
cout << endl;
cout << "wstring:" << endl;
wstring str2 = L"abecą";
wcout << str2 << endl;
cout << cvu32.to_bytes(str2) << endl;
write_hex(cout, str2);
cout << endl;
}
Dla leniwych: https://ideone.com/VIRApH
A więc to nie kwestia kodowania wewnątrz programu, a systemu operacyjnego. Linux od dawna wspiera utf-8. Za to nie wspiera utf16/utf32 jako locale, bo są niekompatybilne z ASCII.
Więc wewnątrz swojego programu możesz używać wstring, zakodowanego jako utf16, ale już nie wypiszesz na konsolę bez konwersji. EDIT: Trzeba, jak zostało wspomniane poniżej w innych postach, ustawić locale, na zgodne z systemem.
Swoją drogą, codecvt_utf8 jest deprecated :), ale nie ma dla niego alternatywy w bibliotece standardowej. Nad wsparciem dla unicode pracuje podgrupa w komitecie standaryzacyjnym. Może w końcu kiedyś udam im się wypracować to co inne języki, nawet te młodsze, już dawno mają ;)
Więc może zainteresuj się boost.locale.