考虑以下示例:
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/