【问题标题】:Why is operator<< overload not found?为什么找不到 operator<< 重载?
【发布时间】:2021-08-23 05:01:19
【问题描述】:

我在全局命名空间中为time_point 声明了一个operator&lt;&lt; 重载,还在a 命名空间中为a::Foo 声明了一个重载。当我尝试在命名空间a 中定义的函数中打印time_point 时,出现错误:

二进制表达式的操作数无效。

为什么会这样,最好的解决方案是什么?

#include <iostream>
#include <chrono>

std::ostream &operator<<(std::ostream &os,
                         const std::chrono::system_clock::time_point &time_point);
namespace a {
class Foo;
std::ostream &operator<<(std::ostream &os, const a::Foo &foo);
void print_time() {
  std::cout << std::chrono::system_clock::now(); // error here!
}
}

int main() {
  a::print_time();
}

【问题讨论】:

  • 因为Argument-dependent lookup。将重载放在namespace std { /* operator overload */ } 中使其工作,但老实说,我不知道这是否完全正确或一个好的解决方案。
  • 定义一个新函数可能比为标准类型重载&lt;&lt; 运算符更好,一些未来的标准可能会声明自己的运算符,这可能与你的模棱两可
  • @churill 这是不允许的(请参阅17.6.4.2.1)。也不能保证标准库已经不提供这样的重载。在这种情况下,过载将变得模棱两可。整个想法一开始就不好。
  • 如果你想给std添加一个可接受的函数,你必须创建自己的类(可以从标准类派生)

标签: c++ c++11 namespaces operator-overloading


【解决方案1】:

原因 很简单:a::operator&lt;&lt; shadows 你的::operator&lt;&lt; 因为它们的名字相同。这就是为什么操作员基本上必须与其类共享一个命名空间:这种阴影是意料之中的,因此 ADL(如 cmets 中所讨论的)是找到它们的唯一可靠方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-06-12
    • 1970-01-01
    • 1970-01-01
    • 2018-04-06
    • 2011-08-30
    • 2015-06-01
    • 1970-01-01
    相关资源
    最近更新 更多