2013-02-19 3 views
2

Я хотел бы знать, почему следующие operator<< перегрузок существуют для basic_ostream «s char частичных-специализаций:Почему существуют перегрузки 'operator <<' для частичной специализации 'char' для std :: basic_ostream?

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); 

Почему я Заботиться знать:

Я считаю, перегруженными в лучшем случае избыточным и в целом громоздким:

    не
  1. следующие перегрузок для неспециалистов типов шаблонов уже существуют, и обеспечить 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); 
    
  2. signed char и unsigned char не являются символьными типами, (есть нет char_traits для них) и они должны использоваться как целые значения (особенно в контексте stdint.hint8_t, uint8_t и т. д.). Однако эти перегрузки контрастируют с обеими этими точками; один должен играть в игры, чтобы обойти эти раздражающие, такие как:

    • явно приводится к signed charsigned short, unsigned char к unsigned short и signed char* или unsigned char* к void* для каждого сценария использования.
      • который требует обходной перегрузки функций или частичной специализации шаблона в коде пользователя.
    • с использованием эквивалента wchar_tbasic_ostream, чтобы избежать этих нежелательных функциональных перегрузок.
      • , что, вероятно, снижает эффективность кода пользователя.

    В обоих случаях код пользователя выглядит уродливее, чем должно быть.

+1

@LokiAstari Он имеет то же представление, что и один из них, но это особый тип. –

+0

Просто * что * об IOStreams is * not * громоздко? –

+1

Я думаю, что ваша реальная проблема заключается не в том, что существуют перегрузки, а в том, что они ведут себя так, как будто вы передаете символьные данные, а не целые числа. Разве это не проблема? –

ответ

1

Перегрузки необходимы, чтобы оператор мог использоваться без указания всех типов шаблонов. Если типы совпадают, компилятор просто использует правильную перегрузку. Если они не совпадают, они должны либо делать неявные преобразования (нежелательные), либо явно указывать все типы шаблонов, и я даже не уверен, что есть синтаксис, который позволит вам это сделать.

+0

В моем примере обхода мы уже должны явно вводить отдельные значения в 'signed short' или' unsigned short' и указатели на 'void *'; эти типы аргументов явно предоставляются как перегрузки функций-членов. Я предполагаю, что альтернатива должна была бы включать перегрузки функции-члена для 'signed char' и' unsigned char' для всех 'basic_stream'. –

1

Черты характера и различные перегрузки символов не связаны.

полукокса черты о типе полукокса и обработки выходного потока на, в то время как символьные перегрузки должны делать с типами символьных вставленных. Подумайте о basic_ostream<wchar_t> против operator<<(basic_ostream, char) например.

Вы также должны учитывать, что это реализация определена, является ли простой символ signed или unsigned. Также

3.9.1 Основные типы [basic.fundamental]
1 ... Обычный символ, подписанный полукокса и неподписанные символ три различных типа.

Таким образом, перегрузка для всего char или const char* не все возможности. Я думаю, что определение этих перегрузок должно быть полным и охватывать все основные типы.

+0

Я понимаю, что второй тип шаблона 'basic_ostream' предназначен для форматирования самого элемента basic_ostream, а не' operator << 'input-arguments. 'char',' signed char' и 'unsigned char' - три разных типа C и C++; (да, представление 'char' совпадает с представлением' signed char' или 'unsigned char', но это не связано с моей точкой.) Дело в том, что' char' и 'wchar_t' являются единственными символьными типами, (в стандарте C++ 03:) 'char_traits',' basic_string' и 'basic_ios' имеют смысл только для этих типов; Литералы c-string могут создаваться только для типов 'char' или' wchar_t'. –

+0

Я хочу сказать, что тип 'signed char' и' unsigned char' должен рассматриваться как любой другой целочисленный (и не-charcter) тип. В настоящее время 'signed char integer = 33; std :: cout << integer' будет печатать '!', а не '33', как ожидалось. –