Search code examples
c++templatestypedefstdstring

Using basic_string to declare a new type of string


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?


Solution

  • 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.