为什么运营商<< std :: ostream和char之间的函数是非成员函数吗?

时间:2015-07-07 16:54:51

标签: c++ c++11 ostream

当我运行以下程序时

#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作为参数类型的重载。函数调用std::cout.operator<<(a)被解析为std::ostream::operator<<(int),这解释了输出。

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

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

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

我的问题是为什么声明/定义为非成员函数?是否存在阻止其成为会员职能的已知问题?

2 个答案:

答案 0 :(得分:12)

std::basic_ostream的一组插入器包含用于将charsigned charunsigned char等插入basic_ostream<char, ...>流的部分特化。请注意,这些特化仅适用于basic_ostream<char, ...>个流,不适用于基于任何其他字符类型的basic_ostream<wchar_t, ...>流或流。

如果您将这些独立模板移到主basic_ostream定义中,它们将适用于basic_ostream的所有专精形式。显然,图书馆作者希望防止这种情况发生。

我真的不知道为什么他们想在更通用的基础上引入这些专业

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

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

C字符串插入器也存在相同的情况。除了更通用的插入器

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

等等。

答案 1 :(得分:4)

一个原因是遵循一般的C ++建议,更喜欢非成员非友元函数到成员函数。这是Scott Meyer的 Effective C ++ 中的第23项。这在stackoverflow中进行了讨论。