Using cout with basic_string <unsigned char>
cout works with the string (aka basic_string<char>
) and all room types ( int
, char
, unsigned char
, double
etc.). However, it cannot handle basic_string<unsigned char>
.
#include <iostream>
#include <string>
int main()
{
std::basic_string<unsigned char> zzz(3, 'z');
std::cout << zzz << std::endl;
return 0;
}
It doesn't compile with
error: invalid operands to binary expression ('ostream' (aka 'basic_ostream<char>') and 'std::basic_string<unsigned char>')
I expect this to behave exactly like a string. Is there a reason why ostream is not processing std::basic_string<unsigned char>
?
source to share
The standard defines the following template operator:
template <class CharT, class Traits, class Allocator>
std::basic_ostream<CharT, Traits>&
operator<<(std::basic_ostream<CharT, Traits>& os,
const std::basic_string<CharT, Traits, Allocator>& str);
This means you can transfer std::string
to std::cout
and std::wstring
from std::wcout
. You cannot transfer std::wstring
to std::cout
.
Your problem is that it std::cout
uses the character type char
, not unsigned char
.
You can define an additional operator in the global namespace if you like.
typedef std::basic_string<unsigned char> ustring;
std::ostream& operator << (std::ostream& stream, const ustring& str) {
if (const auto len = str.size())
stream.write(reinterpret_cast<const char*>(&str[0]), len);
return stream;
}
source to share
There is no corresponding overload in the standard library std::ostream
. However, you can provide your own overload. Although you may have different behavior for characters that are notstd::isprint
#include <iostream>
#include <string>
std::ostream& operator << (std::ostream& os, const std::basic_string<unsigned char>& str){
for(auto ch : str)
os << static_cast<char>(ch);
return os;
}
int main()
{
std::basic_string<unsigned char> zzz(3, 'z');
std::cout << zzz << std::endl;
return 0;
}
Printing
zzz
source to share
The global object std::cout
has a type std::ostream
that is an alias for std::basic_ostream<char>
. A matching operator std::basic_string::operator<<
that requires std::basic_string<CharT>
and std::basic_ostream<CharT>
uses the same type CharT
. In your example, you are using std::basic_string<unsigned char>
and std::basic_ostream<char>
, which are not supported because unsigned char
and char
are different types. Note that signed char
and are unsigned char
always different from char
.
char is the type of character representation that can be most efficiently handled on the target system (has the same representation and alignment as a signed char or unsigned char, but is always a separate type). [...] Link .
source to share