为什么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::ostream
和char
之间的operator<<
函数在其他地方被声明为:
std::ostream& operator<<(std::ostream& out, char c);
否则, std::cout << a
将parsing为std::ostream::operator<<(int)
。
我的问题是为什么声明/定义为非成员函数? 有没有已知的问题阻止它成为一个成员函数?
std::basic_ostream
的插入器集包括用于将char
, signed char
, unsigned 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中讨论。