cout работает со строкой (a.k.a. basic_string<char>
) и все типы номеров (int
, char
, unsigned char
, double
, так далее.). Однако он не может справиться 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;
}
Это не компилируется с
error: invalid operands to binary expression ('ostream' (aka 'basic_ostream<char>') and 'std::basic_string<unsigned char>')
Я ожидаю, что это будет вести себя так же, как строка. Есть ли причина, по которой ostream не справляется? std::basic_string<unsigned char>
?
Там нет соответствия std::ostream
перегрузка для него в стандартной библиотеке. Вы можете, однако, обеспечить свою собственную перегрузку. Хотя вы можете иметь другое поведение для персонажей, которые не std::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;
}
Печать:
zzz
Стандарт определяет следующий оператор шаблона:
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);
Это означает, что вы можете транслировать std::string
в std::cout
, а также std::wstring
в std::wcout
, Вы не можете поток std::wstring
в std::cout
,
Ваша проблема в том, что std::cout
использует тип символа char
не unsigned char
,
Вы можете определить дополнительный оператор в глобальном пространстве имен, если хотите.
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;
}
Как с, скажем, std::vector<char>
здесь нет очевидного поведения по умолчанию, поэтому оно не предоставляется из коробки. Это Можно Работа; вам просто нужно определить как это работает самостоятельно.
Глобальный объект std::cout
имеет тип std::ostream
который является псевдонимом для std::basic_ostream<char>
, Соответствующий оператор std::basic_string::operator<<
который требует, чтобы std::basic_string<CharT>
и std::basic_ostream<CharT>
поделиться одним и тем же типом CharT
, В вашем примере вы используете std::basic_string<unsigned char>
а также std::basic_ostream<char>
который не поддерживается, так как unsigned char
а также char
разные типы. Обратите внимание, что signed char
а также unsigned char
всегда отличны от char
,
char — тип для символьного представления, который может быть наиболее эффективно обработан в целевой системе (имеет такое же представление и выравнивание, что и знаковый или неподписанный символ, но всегда является отдельным типом). […] Ссылка на сайт.