c++ - 命名空间中的 ostream 运算符 << 隐藏了其他 ostream::operator

标签 c++ g++ operator-overloading language-lawyer ostream

<分区>

使用带有 --std=c++14 的 gcc 版本 5.2.0 (GCC),如果命名空间 MyNamespace 中被注释掉的运算符 ostream 未被注释,则以下代码不再编译。这是错误还是功能? (用 g++ -c --std=c++14 x.cxx 编译)

#include <string>
#include <iostream>

typedef std::pair<std::string, std::string> StringPair;

std::ostream& operator<<( std::ostream&, const StringPair &pair) {
  std::cout <<pair.first<<"."<<pair.second;
}

namespace MyNamespace {
  class MyClass {};
  //std::ostream& operator<< (std::ostream&, const MyClass &);
  void xxx ();
}

void MyNamespace::xxx () {
  StringPair pair;pair.first="1";pair.second="2";
  std::cout <<pair<<std::endl;
}

我从运算符 << uncommented 得到的错误消息是:

x.cxx: In function ‘void MyNamespace::xxx()’:
x.cxx:18:13: error: no match for ‘operator<<’ (operand types are ‘std::ostream {aka std::basic_ostream<char>}’ and ‘StringPair {aka std::pair<std::__cxx11::basic_string<char>, std::__cxx11::basic_string<char> >}’)
std::cout <<pair<<std::endl;
         ^

最佳答案

如前所述here , 这是 name hiding 的例子.通过定义 operator<<在命名空间 MyNamespace隐藏来自更高命名空间(如全局)的所有定义。

请注意,如前所述 here :

[...]this feature doesn't interfere with Koenig lookup [...], so IO operators from std:: will still be found.

( details about Koenig lookup )

解决方案是使用 using 引用其他命名空间中的重载。指令,如所述herehere . Michael Nastenko 在评论中提到了这一点。

因此 using ::operator<<; , 与 ::引用全局命名空间。

这样代码会变成:

#include <string>
#include <iostream>

typedef std::pair<std::string, std::string> StringPair;

std::ostream& operator<<(std::ostream& os, const StringPair &pair) {
    os << pair.first << '.' << pair.second;
    return os;
}

namespace MyNamespace {
    class MyClass {};
    using ::operator<<;
    std::ostream& operator<< (std::ostream&, const MyClass &);
    void xxx();
}

void MyNamespace::xxx() {
    StringPair pair("1","2");
    std::cout<<pair<<std::endl;
}

int main() {
    MyNamespace::xxx();
    return 0;
}

example on Coliru

关于c++ - 命名空间中的 ostream 运算符 << 隐藏了其他 ostream::operator,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49049912/

上一篇:c++ - 线程和 sleep

下一篇:C++串行连接

相关文章:

c++ - 如何使用结构化绑定(bind)来复制类型为 T& 的元素的类似元组的对象?

c++ - C++ 指针运算符列表

c++ - operator void*() 转换仍然是 C++ 库的一部分吗?

c++ - 字符串运算符+(重载)char数组和string.in cpp中的不同行为

c++ - 如何在 C++ 中重载非交换运算符的两种可能性?

c++ - 这是实现通用 operator== 和 operator< 的安全方法吗?

c++ - 在 linux 中使用 opencv 从 windows 共享文件夹中读取图像

c++ - Vim 将长字符串分成几个

c++ - 尽管在参数中提供了所有需要的库,但为什么编译器会抛出 "undefined reference to ..."

c++ - g++ 4.9.4 缺少 LLONG_MAX?