我有关于运算符重载的问题,并附带了一个有趣的代码:
#include <iostream>
class A {
public:
operator bool() {
return true;
}
bool operator!() {
return false;
}
};
int main() {
A a;
if (!a) {
std::cout << "HELLO";
} else {
std::cout << "WORLD";
}
std::cout << std::endl;
return 0;
}
首先会叫什么,之后会怎样?为什么?这是在cppreference中的任何地方描述的吗?
P.S。对于那些认为我自己无法执行此代码的downvoters和其他人。我可以。我做到了。我已经多次改变它以查看它的行为。所以呢?这不是解释。我已经要求提供一个明确的参考,说明此代码遵循的规则。它在我的机器上如何工作的信息没有回答这个问题 - 如果这甚至不能在不同环境(操作系统,可能是处理器等)中移植,该怎么办?
答案 0 :(得分:7)
它的工作原理很简单。编译器解析源并看到if(!a)
。然后,它会检查A
是否定义了operator!
。就是这样。因此被调用。
如果看到if(a)
,则会检查A
是否可以转换为可以在if
条件下使用的内容。碰巧它确实可以转换。
如果没有operator!
,则编译器会检查A
是否可以转换为可能在逻辑上否定的内容。 然后将执行转换为bool。
a + 1
将编译。我认为不是我们想要的。最好只在bool
符合上下文的情况下允许它。您可以通过明确标记转换运算符来实现:
explicit operator bool() {
return true;
}
答案 1 :(得分:4)
!a
只不过是您定义的a.operator!()
的语法糖:这是编译器的首选。
因此转换为bool
运算符绝不是候选者。
你可以通过写
来设计后者if (!(bool)a) {