如果以下test-programm
#include <iostream>
class A {
public:
A() {}
explicit operator bool() const {
std::cout << __PRETTY_FUNCTION__ << std::endl;
return true;
}
// explicit operator bool() {
// std::cout << __PRETTY_FUNCTION__ << std::endl;
// return true;
// }
const operator int() const {
std::cout << __PRETTY_FUNCTION__ << std::endl;
return 1;
}
operator int() {
std::cout << __PRETTY_FUNCTION__ << std::endl;
return 1;
}
};
int main() {
A a;
if (a) {
std::cout << "bool()" << std::endl;
}
if (a + 0) {
std::cout << "int()" << std::endl;
}
}
运行,输出
int A::operator int()
bool()
int A::operator int()
int()
而不是
bool A::operator _Bool()
bool()
int A::operator int()
int()
我的期望(以及如果取消注释评论的部分,你会得到什么)。
所以问题是,转换为非const-int优先级转换为const-bool的规则是什么?
答案 0 :(得分:9)
对引用绑定执行重载解析时,首选的是较少cv限定的类型。这将在13.3.3.2p3中讨论,给出的例子如下:
struct X {
void f() const;
void f();
};
void g(const X& a, X b) {
a.f(); // calls X::f() const
b.f(); // calls X::f()
}
请注意,将对象绑定到成员函数(13.3.1.1.1p2)的隐式对象参数是引用绑定(13.3.3.1.4)。
转换运算符被视为成员函数(13.3.1.5),用于重载解析(13.3p2)。上下文转换为bool
具有初始化的语义(4p4)。
重要的是,在考虑转换运算符本身之间的重载分辨率(13.3.3p1)之后,转换运算符的返回类型所需的任何转换都只被视为。
解决方案是确保所有转换运算符具有相同的const
- 限定条件,尤其是标量类型。
答案 1 :(得分:4)
将转换为非const-int优先级转换为const-bool的规则是什么?
使用非const对象的const成员函数,需要将非const对象转换为const-object。这就是operator int()
与operator bool() const
匹配得更好的原因。
为了使它更清楚一点,如果要删除int运算符,第一个bool上下文(第一个if)真正发生的是:
if ( const_cast<const A&>(a).operator bool() ) {
相反,会发生什么:
if ( a.operator int() )