0

What's the correct usage of std::basic_string? I am trying to re-declare the string type with an unsigned char type.

#include <iostream>

using namespace std;

int main()
{
    typedef basic_string<unsigned char> ustring;

    unsigned char unsgndstring[] = {0xFF,0xF1};
    ustring lol = unsgndstring;

    cout << lol << endl;

    return 0;
}

When I try the above code, I get:

main.cpp:25:10: error: no match for 'operator<<' (operand types are 'std::ostream {aka std::basic_ostream}' and 'ustring {aka std::basic_string}')
     cout << lol << endl;
          ^

Why am I getting that? What's the correct way to declare a new string type that can hold unsigned chars?

4
  • Even if basic_string<unsigned char> works, that doesn't mean all code out there written to use basic_string<char> will be compatible with it. Is there a particular reason you think there's supposed to be an operator<< that support this? Commented May 16, 2018 at 16:55
  • Where is #include <string>? Commented May 16, 2018 at 16:56
  • 1
    the correct usage is to use one of its specializations, eg std::string ;) Commented May 16, 2018 at 16:57
  • 1
    Hope for future. open-std.org/JTC1/SC22/WG21/docs/papers/2018/p0482r3.html Commented May 16, 2018 at 16:58

1 Answer 1

3

Your ustring is not the problem - it's just that noone has told the compiler how to print a ustring. There is no general way to do this mostly because different character types may require different treatment (with regards to locale and encoding).

To fix this, you would need to define your own operator<<

typedef basic_string<unsigned char> ustring;

ostream& operator<<(ostream& stream, const ustring& str)
{
    // Print your ustring into the ostream in whatever way you prefer
    return stream;
}

However, I do wonder what your use case for using basic_string here is. In my experience, byte sequences that don't directly translate into textual data is better served by an std::vector<uint8_t>, and strings with larger ranges than ASCII (if you cannot use UTF-8 for some reason) by an std::wstring. The former obviously does not have any direct output methods (you would again need to come up with something custom, but in that case it is far more obvious what is intended), and the latter supports outputting directly into std::wcout etc.

Sign up to request clarification or add additional context in comments.

3 Comments

I disagree with switching to wide chars when your string chars have larger ranges than ASCII - unless you're stuck on Windows with its UTF-16 (?) obsession, I'd instead recommend mentally dropping the byte/character association and storing UTF-8 on top of the bytes in a bog-standard std::string. Stream them to std::cout as usual and let the console/file viewer/whatever deal with the encoding. Downside of course being now you need a UTF-8 library for some string operations (where encoding awareness is a concern) — but that's almost trivial to solve.
Good point. Related reading: UTF-8 Everywhere
You are right, I think I need to switch to vector instead. Thanks for the tip.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.