Почему существуют перегрузки 'operator<<' для частичных специализаций 'char' в std:: basic_ostream?
Я хотел бы знать, почему следующее operator<<
существуют перегрузки для basic_ostream
"s char
частичных специализация:
template< class Traits >
basic_ostream<char,Traits>& operator<<( basic_ostream<char,Traits>& os,
char ch );
template< class Traits >
basic_ostream<char,Traits>& operator<<( basic_ostream<char,Traits>& os,
signed char ch );
template< class Traits >
basic_ostream<char,Traits>& operator<<( basic_ostream<char,Traits>& os,
unsigned char ch );
template< class Traits >
basic_ostream<char,Traits>& operator<<( basic_ostream<char,Traits>& os,
const char* s );
template< class Traits >
basic_ostream<char,Traits>& operator<<( basic_ostream<char,Traits>& os,
const signed char* s );
template< class Traits >
basic_ostream<char,Traits>& operator<<( basic_ostream<char,traits>& os,
const unsigned char* s );
Почему я хочу знать:
Я нахожу перегрузки в лучшем случае излишними и обычно громоздкими:
Следующие перегрузки для неспециализированных типов шаблонов уже существуют и предоставляют
char
а такжеchar*
функциональность:template< class CharT, class Traits> basic_ostream<CharT,Traits>& operator<<( basic_ostream<CharT,Traits>& os, CharT ch ); template< class CharT, class Traits> basic_ostream<CharT,Traits>& operator<<( basic_ostream<CharT,Traits>& os, char ch ); template< class CharT, class Traits > basic_ostream<CharT,Traits>& operator<<( basic_ostream<CharT,Traits>& os, const CharT* s ); template< class CharT, class Traits > basic_ostream<CharT,Traits>& operator<<( basic_ostream<CharT,Traits>& os, const char* s );
signed char
а такжеunsigned char
не являются типами символов, (нетchar_traits
для них), и они должны быть использованы как целочисленные значения (особенно вstdint.h
контекстint8_t
,uint8_t
и т. д.) Однако эти перегрузки контрастируют с обоими этими точками; Нужно играть в игры, чтобы обойти эти неприятности, такие как:- явное приведение
signed char
вsigned short
,unsigned char
вunsigned short
, а такжеsigned char*
или жеunsigned char*
вvoid*
для каждого варианта использования.- который требует обхода функции перегрузки функции или частичной специализации шаблона в пользовательском коде.
- с использованием
wchar_t
эквивалентbasic_ostream
чтобы избежать этих нежелательных перегрузок функций.- что, вероятно, снижает производительность пользовательского кода.
В обоих случаях код пользователя выглядит хуже, чем нужно.
- явное приведение
2 ответа
Перегрузки необходимы для того, чтобы оператор мог использоваться без указания всех типов шаблонов. Если типы совпадают, компилятор просто использует правильную перегрузку. Если они не совпадают, либо нужно выполнить неявные преобразования (нежелательно), либо вам нужно явно указать все типы шаблонов, и я даже не уверен, что существует синтаксис, который позволил бы вам это сделать.
Черты характера и различные перегрузки символа не связаны.
Черты характера относятся к типу символа и обработке выходного потока, тогда как перегрузки символа имеют отношение к вставленным типам символов. Думать о basic_ostream<wchar_t>
против operator<<(basic_ostream, char)
например.
Вы также должны учитывать, что это определяется реализацией, является ли обычный символ signed
или же unsigned
, Также
3.9.1 Фундаментальные типы [basic.fundamental]
1... Обычный символ, подписанный символ и неподписанный символ - это три разных типа.
Итак, перегрузка для всего char
или же const char*
не охватывает все возможности. Я предполагаю, что определение этих перегрузок должно быть полным и охватывать все основные типы.