¿Por qué es operator < function entre std:: ostream y char una función no miembro?


Cuando ejecuté el siguiente programa

#include <iostream>

int main()
{
   char c = 'a';
   std::cout << c << std::endl;
   std::cout.operator<<(c) << std::endl;

   return 0;
}

Tengo la salida

a
97

Cavar más en http://en.cppreference.com/w/cpp/io/basic_ostream/operator_ltlt , noté que std::ostream::operator<<() no tiene una sobrecarga que tenga char como el tipo de argumento. La función call std::cout.operator<<(a) se resuelve a std::ostream::operator<<(int), lo que explica la salida.

Asumo que la función operator<< entre std::ostream y char se declara en otra parte como:

std::ostream& operator<<(std::ostream& out, char c);

De lo contrario, std::cout << a resolvería a std::ostream::operator<<(int).

Mi pregunta es ¿por qué se declara/define como una función no miembro? ¿Hay algún problema conocido que impida que sea una función miembro?

Author: πάντα ῥεῖ, 2015-07-07

2 answers

El conjunto de insertadores para std::basic_ostream incluye especializaciones parciales para insertar char, signed char, unsigned char y tales en basic_ostream<char, ...> corrientes. Tenga en cuenta que estas especializaciones están disponibles solo para flujos basic_ostream<char, ...>, no para flujos basic_ostream<wchar_t, ...> o flujos basados en cualquier otro tipo de carácter.

Si mueve estas plantillas independientes a la definición principal basic_ostream, estarán disponibles para todas las formas de especializaciones de basic_ostream. Al parecer, los autores de la biblioteca querían evitar esto de suceder.

Realmente no sé por qué querían introducir estas especializaciones en la parte superior de la más genérica

template<class charT, class traits>
basic_ostream<charT,traits>& operator<<(basic_ostream<charT,traits>&,
                                        char);

Insertador, pero al parecer tenían sus razones(optimización?).

La misma situación existe para los insertadores de cadenas C. Además del insertador más genérico

template<class charT, class traits>
basic_ostream<charT,traits>& operator<<(basic_ostream<charT,traits>&,
                                        const char*);

La especificación de la biblioteca también declara

template<class traits>
basic_ostream<char,traits>& operator<<(basic_ostream<char,traits>&,
                                       const char*);

Y así sucesivamente.

 12
Author: AnT,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-07 17:36:08

Una de las razones es seguir el consejo general de C++ de preferir las funciones no miembro no amigo a las funciones miembro. Este es el ítem 23 en el C++efectivo de Scott Meyer. Esto se discute en stackoverflow.

 4
Author: snow_abstraction,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:46:54