为何使用operator-的前缀表示法会导致重载决议失败
为什么成员operator-会隐藏全局整数二元operator-?
以下代码片段无法编译:
struct HasOperatorMinus { int v; HasOperatorMinus operator-(HasOperatorMinus o) { return operator-(this->v, o.v); } }; auto f(HasOperatorMinus a) { return a - a; }
编译器给出如下错误:
<source>:3:80: error: too many arguments to function call, expected single argument 'o', have 2 arguments 3 | HasOperatorMinus operator-(HasOperatorMinus o) { return operator-(this->v, o.v); } | ~~~~~~~~~ ^~~ <source>:3:22: note: 'operator-' declared here 3 | HasOperatorMinus operator-(HasOperatorMinus o) { return operator-(this->v, o.v); } | ^ ~~~~~~~~~~~~~~~~~~
问题核心在于C++的名称查找规则:当在类的成员函数内部引用operator-时,编译器会优先在当前类的作用域中查找该名称,类中的成员operator-会直接隐藏全局作用域中同名的整数减法运算符。
类中的operator-是成员函数,其签名为HasOperatorMinus operator-(HasOperatorMinus)——作为成员函数,它仅接受一个显式参数(第一个操作数是隐含的this指针)。当你尝试以operator-(this->v, o.v)的形式调用时,编译器在类作用域找到的operator-无法匹配两个int参数,且名称查找在找到类内同名成员后就会停止,不会继续查找全局作用域的版本,因此导致重载决议失败。
要解决这个问题,需要明确指定调用全局作用域的operator-,通过添加全局作用域符号::实现:
struct HasOperatorMinus { int v; HasOperatorMinus operator-(HasOperatorMinus o) { return ::operator-(this->v, o.v); } }; auto f(HasOperatorMinus a) { return a - a; }
内容的提问来源于stack exchange,提问作者TheCppZoo
相关产品推荐
相关产品推荐

