vector<u16string>, cout, ostringstream not working together

vector<u16string>, cout, ostringstream not working together.
see https://groups.google.com/forum/#!topic/alt.comp.lang.learn.c-c++/CY7RxUBj_2c
any clues as to how I can fix this mismatch? this should not be a problem but I guess some UNICODE stuff is unimplemented as yet (2/2014). there is a suggestion as to what to do, but it is unclear exactly what, I saw no code examples.
Perhaps the simplest solution would be to convert from/to UTF-8 for input/output.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
#include <string>
#include <locale>
#include <codecvt>
 
int main()
{
    const std::u16string utf16 = u"Πυθαγόρας ὁ Σάμιος (Pythagoras of Samos)" ;
    
    // http://en.cppreference.com/w/cpp/locale/wstring_convert
    std::wstring_convert<std::codecvt_utf8_utf16<char16_t>,char16_t> codecvt ;
    
    std::cout << codecvt.to_bytes(utf16) << '\n' ;
}

http://coliru.stacked-crooked.com/a/55166222311b305d

Also see: http://en.cppreference.com/w/cpp/locale/wbuffer_convert
Your ograph is defined as a byte output stream (std::ostringstream), so depending on the imbued locale, it can accept various narrow/multibyte strings (ASCII, UTF-8, GB18030, what-have-you), but not 16-bit, 32-bit, or wide strings.

In standard C++, you would convert from UTF-16 to wide and use std::wcout or to UTF-8 and use std::cout, but there is no direct way to print a u16string in C++ (except where the OS provides APIs for that: Windows does). I recommend against 16-bit encodings: Unicode went 32 bit almost 15 years ago.

I have no access to a Windows system so i can't really help with mingw, but why can't you use wide strings?

that's not where it's erroring at (cout). it's erroring at <<. see error messages.
> that's not where it's erroring at (cout). it's erroring at <<. see error messages.

The operator<<() is the same for both.
If it works with std::cout, it will also work with an object of type std::ostringstream

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <string>
#include <locale>
#include <codecvt>
#include <sstream>
 
int main()
{
    const std::u16string utf16 = u"Πυθαγόρας ὁ Σάμιος" ;
    const std::u16string another_utf16 = u"(Pythagoras of Samos)" ;
    
    // http://en.cppreference.com/w/cpp/locale/wstring_convert
    std::wstring_convert<std::codecvt_utf8_utf16<char16_t>,char16_t> codecvt ;
    
    std::ostringstream ograph ; 
    ograph << "the two UTF-16 strings contain: '" << codecvt.to_bytes(utf16) 
           << "' and '" << codecvt.to_bytes(another_utf16) << "'" ;
           
    std::cout << ograph.str() << '\n' ;
}

http://coliru.stacked-crooked.com/a/cb846564c34ea78d

Doesn't solve your problem though (I hdn't clicked on the link earlier).
The GNU standard C++ library does not have the C++11 code conversion facets.
I am using c++11 on gcc.
the errors are now:

ostream.cpp: In function 'int main()':
ostream.cpp:19:45: error: cannot bind 'std::basic_ostream<char>' lvalue to 'std::basic_ostream<char>&&'
ograph<<vu16asciis[1];//"-";
^
In file included from f:/x86_64-4.8.2-release-posix-sjlj-rt_v3-rev3/mingw64/x86_64-w64-mingw32/include/c++/iostream:39:0,
from ostream.cpp:2:
f:/x86_64-4.8.2-release-posix-sjlj-rt_v3-rev3/mingw64/x86_64-w64-mingw32/include/c++/ostream:602:5: error: initializing argument 1 of 'std::basic_ostream<_Cha
rT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&&, const _Tp&) [with _CharT = char; _Traits = std::char_traits<char>; _Tp = std::basic_string<
char16_t>]'
operator<<(basic_ostream<_CharT, _Traits>&& __os, const _Tp& __x)
^
ostream.cpp:20:46: error: cannot bind 'std::basic_ostream<char>' lvalue to 'std::basic_ostream<char>&&'
ograph<<vu16blockss[1];//u"\u0A1F";//2591
^
In file included from f:/x86_64-4.8.2-release-posix-sjlj-rt_v3-rev3/mingw64/x86_64-w64-mingw32/include/c++/iostream:39:0,
from ostream.cpp:2:
f:/x86_64-4.8.2-release-posix-sjlj-rt_v3-rev3/mingw64/x86_64-w64-mingw32/include/c++/ostream:602:5: error: initializing argument 1 of 'std::basic_ostream<_Cha
rT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&&, const _Tp&) [with _CharT = char; _Traits = std::char_traits<char>; _Tp = std::basic_string<
char16_t>]'
operator<<(basic_ostream<_CharT, _Traits>&& __os, const _Tp& __x)
^
ostream.cpp:21:45: error: cannot bind 'std::basic_ostream<char>' lvalue to 'std::basic_ostream<char>&&'
ograph<<vu16asciis[2];//"*";
^
In file included from f:/x86_64-4.8.2-release-posix-sjlj-rt_v3-rev3/mingw64/x86_64-w64-mingw32/include/c++/iostream:39:0,
from ostream.cpp:2:
f:/x86_64-4.8.2-release-posix-sjlj-rt_v3-rev3/mingw64/x86_64-w64-mingw32/include/c++/ostream:602:5: error: initializing argument 1 of 'std::basic_ostream<_Cha
rT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&&, const _Tp&) [with _CharT = char; _Traits = std::char_traits<char>; _Tp = std::basic_string<
char16_t>]'
operator<<(basic_ostream<_CharT, _Traits>&& __os, const _Tp& __x)
^
ostream.cpp:22:46: error: cannot bind 'std::basic_ostream<char>' lvalue to 'std::basic_ostream<char>&&'
ograph<<vu16blockss[4];//u"\u0A1C";//2588
^
In file included from f:/x86_64-4.8.2-release-posix-sjlj-rt_v3-rev3/mingw64/x86_64-w64-mingw32/include/c++/iostream:39:0,
from ostream.cpp:2:
f:/x86_64-4.8.2-release-posix-sjlj-rt_v3-rev3/mingw64/x86_64-w64-mingw32/include/c++/ostream:602:5: error: initializing argument 1 of 'std::basic_ostream<_Cha
rT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&&, const _Tp&) [with _CharT = char; _Traits = std::char_traits<char>; _Tp = std::basic_string<
char16_t>]'
operator<<(basic_ostream<_CharT, _Traits>&& __os, const _Tp& __x)
^
ostream.cpp:23:2: error: 'wstring_convert' is not a member of 'std'
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>,char16_t> codecvt0;
^
ostream.cpp:23:23: error: 'codecvt_utf8_utf16' is not a member of 'std'
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>,char16_t> codecvt0;
^
ostream.cpp:23:47: error: expected primary-expression before 'char16_t'
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>,char16_t> codecvt0;
^
ostream.cpp:23:47: error: expected ';' before 'char16_t'
ostream.cpp:24:17: error: 'codecvt0' was not declared in this scope
std::wcout<<codecvt0.to_bytes(ograph.str());
^
Last edited on
gcc uses codecvt.h
<bits/codecvt.h> is gcc's internal header, which isn't related to <codecvt>, the C++11 header which is not implemented in gcc's library (Microsoft's and clang's libraries both implemented it back in 2010, for comparison)

I recommend boost.locale, it's known to work with mingw and is portable (or simply wide strings if you don't need much)
Last edited on
I can't get boost to build under mingw-w64. the batch files are all wrong, and the boost folks know it.
THe Nuwen build of MinGW is w64 and includes prebuilt Boost 1.55.0 http://nuwen.net/mingw.html
tried
1
2
3
4
typedef std::basic_ostringstream<char16_t> uostringstream;
typedef std::basic_ostringstream<char16_t> u32ostringstream;
std::basic_ostream<char16_t> ucout;
std::basic_ostream<char32_t> u32cout;

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2035.pdf
with appropriate changes
only to find that the compiler still barks at it.

I also can't get boost to build on mingw-w64.
Last edited on
Topic archived. No new replies allowed.