c++ - 为什么cout << "hello"选择operator<<的非成员版本?

标签 c++ operator-overloading iostream

今天我试图了解与运算符<<及其重载相关的事情。

让我们看一下这段代码:

cout.operator<<("hello");   // +16 overloads -> implicit conversion to void*
cout.operator<<(123);       // +16 overloads

operator<<(cout,"hello");   // +13 overloads
operator<<(cout, 123);      // ERROR: no overload

cout << "hello";            // +13 overloads ---> non-member version!
cout << 123;                // +16 overloads ---> member version!

感谢 Visual Studio 的 Intellisense,我可以检测每一个它可以提供多少重载。

我得出的结论是:

  • 非成员运算符<<重载为13
  • 成员运算符<<重载(对于 cout)是 16

我有这些问题:

正如您从最后两行中看到的,当使用带有 const char[] 的 cout 时,选择了非成员重载。

  • 为什么 cout 对象没有一个成员运算符<<,它接受一个 const char[]?

此外,在第四行我们得到一个错误,因为没有非成员运算符<< 重载需要一个整数。

  • 为什么没有接受整数的非成员运算符<<?

最后一点

  • 为什么 cout << “hello”选择运营商的非成员(member)版本<< ?

可能是因为有一个特定的非成员运算符<<重载是const char[]的良好候选者,而不是采用的成员运算符<<重载无效*

最佳答案

Why isn't there a member operator<< for the cout object which takes a const char[]?

字符串是分开处理的。为 std::basic_string 创建成员运算符将要求所有流都依赖于 std::basic_string功能,这并不总是可取的。所有成员运算符都用于内置语言类型,但 std::basic_string相反,它是一个类,因此它具有非成员运算符重载。有人可能会争辩说 const char[] (衰减为 const char* )是内置类型,但是 operator<<溪流 const char*类似于 std::basic_string ,将这些实现拆分到库的两个不同区域是没有意义的。处理字符串的功能,无论是使用数组还是类,通常都组合在一起。

Why isn't there a non-member operator<< which takes an integer?

因为不需要一个。它已经作为成员运算符存在。您不应该直接 调用成员运算符(除非您需要,而您的示例不需要)。您应该正常使用运算符 ( stream << ... ) 并让重载决策根据参数、作用域等选择正确的成员或非成员运算符。如果您考虑一下,非成员重载会导致歧义错误。应该stream << 123调用stream.operator<<(123)::operator<<(stream, 123) ?只能有一个选择,否则编译失败。

Why does cout << “hello” choose the non-member version of the operator<< ? Maybe because there is a particular non-member operator<< overload which is a good candidate for a const char[], rather than the member-operator<< overload which takes a void*?

这正是原因所在。类型 const char[]参数更适合窄字符串文字,然后是未类型化的 void*指针。因此,如果两个运算符都在范围内(并且 const char[] 重载仅在使用 #include <string> 时才在范围内),那么编译器将选择更匹配的重载。

关于c++ - 为什么cout << "hello"选择operator<<的非成员版本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39336769/

相关文章:

c++ - unicode 字符的相等性

c++ - 没有卡尔曼滤波器的 BackgroundSubtractorGMG?

c++ - 按位重载 OR ('|' ) 链接操作未按预期工作

c++ - 错误 C++ 2679(二进制 '>>' : no operator found which takes a right-hand operand of type 'const std::string' (or there is no acceptable conversion))

c++ - 实现与 <<? 一起使用的有界字符串格式化运算符的有效方法

C++ 模板参数继承

c++ - 用于 IVR 应用的 SIP RTP 栈

c++ - 在 C++ 中重载运算符 +

c++ - 为什么 sleep() 会阻塞 std::ostream

c++ - C++读取二进制文件