为什么在上下文转换中没有发生显式的bool()转换

时间:2014-02-27 09:39:43

标签: c++ c++11 operator-overloading

如果以下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的规则是什么?

2 个答案:

答案 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() )