[英]Are there different rules regarding ADL or naming clashes with regard to overloaded operators?
我认为这个例子最能说明我的问题:
namespace N {
class C {
public:
friend bool operator==(const C& c, const C& x) {
return true;
}
friend bool f(const C& c, const C& x) {
return true;
}
};
class D {
public:
bool operator==(const D& x) {
bool a = C{} == C{}; // this works
return true;
}
bool f(const D& x) {
bool a = f(C{}, C{}); // this does not work
return true;
}
};
}
我一直认为重载运算符就像函数一样,除了'调用语法',如果你愿意的话。 我刚才注意到ADL或名称查找规则中的上述差异(我不知道哪一个)。
有人可以解释为什么找到bool operator==(const C& c, const C& x)
但是bool f(const C& c, const C& x)
不是?
你的D::f
隐藏了 C::f
; 如果你将后者重命名为C::g
并调整调用,那么它工作正常(显示该函数可以找到并访问得很好)。
您的代码实际上并不直接调用操作符函数,但这是通过语言为您完成的。 因此,您没有使用运算符函数的名称 ,因此不应用名称隐藏。
如果你编写operator==(C{}, C{})
(而不是C{} == C{}
),那么你会看到与f(C{}, C{})
相同的行为( 演示 ) 。
所以,当你说“我总是把重载的操作符视为除了'调用语法'之外的功能之外,如果你愿意的话”,那么你已经触及了头脑。
这是你的一些标准:
[C++11: 13.5/4]:
通常不直接调用运算符函数; 相反,它们被调用来评估它们实现的运算符(13.5.1 - 13.5.7)。 但是,可以使用operator-function-id作为函数调用语法(5.2.2)中函数的名称来显式调用它们。 [例如:complex z = a.operator+(b); // complex z = a+b; void* p = operator new(sizeof(int)*n);
- 末端的例子]
[C++11: 3.3.7/4]:
[..] 4)在成员函数中声明的名称隐藏了一个同名的声明,其范围扩展到或超过了成员函数类的末尾。 [..]
[C++11: 3/4]:
名称是使用标识符 (2.11), operator-function-id (13.5), literal-operator-id (13.5.8), conversion-function-id (12.3) .2),或表示实体或标签的 模板ID (14.2)(6.6.4,6.1)。
(这里的[qualified] operator-function-id是::N::C::operator==
。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.