Использование cout с basic_string & lt; unsigned char & gt;

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>?

3

Решение

Там нет соответствия 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

демонстрация

2

Другие решения

Стандарт определяет следующий оператор шаблона:

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;
}
2

Как с, скажем, std::vector<char>здесь нет очевидного поведения по умолчанию, поэтому оно не предоставляется из коробки. Это Можно Работа; вам просто нужно определить как это работает самостоятельно.

1

Глобальный объект 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 — тип для символьного представления, который может быть наиболее эффективно обработан в целевой системе (имеет такое же представление и выравнивание, что и знаковый или неподписанный символ, но всегда является отдельным типом). […] Ссылка на сайт.

0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector