c++ - 无法找到在全局命名空间中定义的运算符

标签 c++

考虑以下示例:

namespace X {
    struct A { static const A aaa; };
    const A A::aaa = {};
}

bool operator == (const X::A &a, const X::A &b) { return true; }
bool workaround (const X::A &a, const X::A &b) { return a == b; }

namespace Y {
    using X::A;

    struct B { const A & an_a() const { static A a; return a; } };

    bool operator == (const B &a, const B &b) { return true; }

    bool foo (const B &b) {
        return b.an_a() == A::aaa;
        //return workaround(b.an_a(), A::aaa);
    }
}

int main () {}

此代码无法编译 foo,因为 == 运算符解析命名空间 Y 中的那个,而不是全局命名空间中的那个。

.code.tio.cpp:17:25: error: invalid operands to binary expression ('const X::A' and 'const X::A')
    return b.an_a() == A::aaa;
           ~~~~~~~~ ^  ~~~~~~
.code.tio.cpp:14:10: note: candidate function not viable: no known conversion from 'const X::A' to 'const Y::B' for 1st argument
    bool operator == (const B &a, const B &b) { return true; }
     ^
1 error generated.

我想我理解这是由于为 C++ 定义了 ADL 的方式,如果类属于命名空间,这似乎明确排除了搜索全局命名空间。但是,这对我来说似乎仍然违反直觉。是否解释了为什么全局命名空间不能包含在要搜索 operator== 的命名空间集中?

最佳答案

为了保持一致性,运算符仅被视为函数名称,并且函数将任何运算符隐藏在封闭范围内(即使参数类型不同)。 (后一条规则大概是为了防止在不同范围内声明的函数之间发生意外的重载决策交互)。

您的 ::operator==(const X::A&,const X::A&)Y::operator 隐藏(在 Y 中) ==(const B&,const B&),并且它不被认为是 X::A 接口(interface)的一部分(因为它不在 immediate namespace X), 所以你找不到它。

如果你愿意改变比较的拼写,你可以使用丑陋的、明确的::operator==(b.an_a(), A::aaa) 而不是添加 workaround

关于c++ - 无法找到在全局命名空间中定义的运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48939721/

相关文章:

c++ - 通过头文件 C++ 使用多个结构

c++ - 将 -lboost_serialization 添加到 Eclipse C++ IDE

c++ - 如何在不使用 opencv 的情况下通过 C++ 中的原始图像形式来降低亮度?

c++ - 为什么我的 Arduino 上没有可用的串行数据?

c++ - 释放抽象类指针

c++ - 静态整数

c++ - C++ 中是否有标准的循环迭代器

c++ - X 类型的值不能用于初始化 X 类型的实体

c# - C# 中具有未定义行为的代码

c++ - 在类中保存函数指针