为什么std :: ostream和char之间的operator <<函数是非成员函数?

当我运行下面的程序

#include <iostream> int main() { char c = 'a'; std::cout << c << std::endl; std::cout.operator<<(c) << std::endl; return 0; } 

我得到了输出

 a 97 

进一步挖掘在http://en.cppreference.com/w/cpp/io/basic_ostream/operator_ltlt ,我注意到, std::ostream::operator<<()没有一个具有char作为参数types的重载。 函数调用std::cout.operator<<(a)被parsing为std::ostream::operator<<(int) ,它解释了输出。

我假设std::ostreamchar之间的operator<<函数在其他地方被声明为:

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

否则, std::cout << a将parsing为std::ostream::operator<<(int)

我的问题是为什么声明/定义为非成员函数? 有没有已知的问题阻止它成为一个成员函数?

std::basic_ostream的插入器集包括用于将charsigned charunsigned char等插入到basic_ostream<char, ...> streams的部分特化。 请注意,这些特化仅适用于basic_ostream<char, ...>stream,不适用于基于任何其他字符types的basic_ostream<wchar_t, ...>stream或stream。

如果将这些独立的模板移动到主basic_ostream定义中,它们将可用于basic_ostream所有特化forms。 显然,图书馆作者想要防止这种情况发生。

我不太清楚为什么他们想把这些专业化推向更通用的领域

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

插入器,但显然他们有他们的理由(优化?)。

Cstring插入器也存在同样的情况。 除了更通用的插件

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

库规范也声明更具体

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

等等。

原因之一是遵循一般的C ++build议,将非成员非友元函数更倾向于成员函数。 这是Scott Meyer的Effective C ++中 23项。 这在stackoverflow中讨论。