c++ - 运算符<< 重载解析 (C++)

标签 c++ c++11 namespaces operator-overloading overload-resolution

下面的代码在 a::b::print 中给出了一个错误功能:Invalid operands to binary expression ('std::ostream' (aka 'basic_ostream<char>') and 'Foo') .
如果我注释掉 operator<<,错误就会消失。命名空间中的重载 b .但我不明白为什么这会有所不同,因为它与 operator<< 具有不同的签名。 namspace 中的过载 a .这是怎么回事?!

#include <iostream>

class Foo {};

namespace a {

  std::ostream &operator<<(std::ostream &os, Foo &foo);
  void print(Foo& foo) {
    std::cout << foo;
  }

  namespace b {
    std::ostream &operator<<(std::ostream &os, double d); // uncomment to resolve error
    void print(Foo& foo) {
      std::cout << foo; // error here
    }
  }
}

最佳答案

作为命名空间 b嵌套在命名空间内 a , 在 b 中声明的名称将隐藏在 a 中声明的名称.当名称查找发生在 a::b::print 中时,它搜索 b ,如果没有找到它要找的内容,则继续在 a 中搜索.所以它确实在 b 中找到了 operator<<并停止寻找,甚至不考虑 a 中合适的那个.当你把它注释掉时,它在 b 中找不到,并继续搜索 a并找到它。你可以通过在命名空间 b 中添加这个来解决这个问题:

using a::operator<<; 
但是,您的代码的真正问题在于您没有正确使用 ADL(参数相关查找)。操作用户定义类型的操作符应该和它们操作的类型在同一个命名空间中。 ADL 所做的是添加额外的 namespace 以进行搜索,以便调用涉及的任何参数(或模板参数)都将自动考虑其 namespace 。 (这就是为什么当您的代码在 std 之外时,您可以将 std 命名空间中提供的运算符用于内置类型。)
所以搬家operator<<超出命名空间 a并进入相同的(全局)命名空间,其中 Foo是。或者,可能更好,移动 Foo进入命名空间 a .

关于c++ - 运算符<< 重载解析 (C++),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67020636/

相关文章:

C++ A星实现--判断节点是否已经在未清项优先队列中

c++ - 如何故意触摸内存页?

c++ - 在 C++ 中为 char 数组数据类型添加的额外字符

c++ - 使用 doxygen 记录枚举值

c++ - 类中的静态字符串常量与常量的命名空间 [c++]

c++ - 当我使用根据 Base 类定义的成员函数指针时,编译器如何调用 Derived 成员函数?

c++ - 使字符串单词等于字符?

c++ - 将 std::unique_ptr.get() 作为参数传递给 addWidget()

php - Pimcore:通过包含类名的字符串创建命名空间对象

.net - 为什么一个类有多个命名空间?