2

I am trying to print out a std::u32string, but I keep getting a compilation error saying:

error: invalid operands to binary expression
  ('ostream' (aka 'basic_ostream<char>') and 'std::u32string' (aka
  'basic_string<char32_t>'))

My code consists of this:

std::u32string test = U"hello";
std::cout << test << std::endl;

Does anyone know what the proper way of printing out a u32string is? I am not interested in using a normal string or wchar strings.

mxdg
  • 314
  • 3
  • 14
  • 2
    `std::u32string` is a `typedef` for `basic_stream ` which will only have `operator<<` for char of type `char32_t` (which is not the case of `cout` or `wcout`). I'll put the question as duplicate because knowing this, the linked question answer yours. – Holt Jul 03 '14 at 17:40
  • 4
    @Holt: The linked question asks *why* this can't be easily done, but it doesn't ask about how to do it. I say this question is not a duplicate. – Brian Bi Jul 03 '14 at 17:49
  • I did see that post before, but I didn't think it was a duplicate because, as Brian said, it doesn't explain how I can actually print u32strings. – mxdg Jul 03 '14 at 18:17

1 Answers1

1

The C++ standard library stream types are templates with the character type as the first template argument. For example, std::ostream is really std::basic_ostream<char>, as you can see from the error message. In general, you can send an std::basic_string<T> to an std::basic_ostream<T>. But std::u32string is std::basic_string<char32_t>, so the types don't match.

Unfortunately there isn't a std::u32cout of type std::basic_ostream<char32_t> or something like that, so your only choice is to convert your UTF-32 encoded string to another encoding.

The following code uses std::wstring_convert to convert the UTF-32 encoded string to UTF-8. A UTF-8 string can be directly printed to std::cout.

std::u32string test = U"hello";
std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> cv;
std::cout << cv.to_bytes(test) << std::endl;

Note that codecvt isn't implemented in libstdc++ yet. I tested this code snippet using clang/libc++.

Brian Bi
  • 111,498
  • 10
  • 176
  • 312
  • I put this into my code, but the declaration of the converter is breaking some other things for some odd reason. I am looking into it. – mxdg Jul 03 '14 at 23:59
  • OP's code was not broken. I am not sure why it had a weird side effect on my code, but it was my fault and not his snippets. I had a bunch of integer counters that were not initialized, and I was incrementing them. Before I added the snippet, they were all somehow automatically initialized to 0 (which was the desired behavior), but was not after I added the line that declared the converter, which broke things. – mxdg Jul 07 '14 at 22:37