c++ - 为什么在上下文转换中不发生显式 bool() 转换

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

如果下面的测试程序

#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 的规则是什么?

最佳答案

在对引用绑定(bind)执行重载决议时,首选 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()
}

请注意,将对象绑定(bind)到成员函数 (13.3.1.1.1p2) 的隐式对象参数是引用绑定(bind) (13.3.3.1.4)。

出于重载决议 (13.3p2) 的目的,转换运算符被视为成员函数 (13.3.1.5)。到 bool 的上下文转换具有初始化(4p4)的语义。

重要的是,转换运算符的返回类型所需的任何转换仅在考虑到转换运算符本身之间的重载解决方案 (13.3.3p1) 之后才考虑

解决方案是确保所有转换运算符具有相同的const-限定符,尤其是对于标量类型。

关于c++ - 为什么在上下文转换中不发生显式 bool() 转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22064519/

相关文章:

c++ - 是否可以在 C++11 中手动设置 istream 失败位

C++:使用整数 move 语义

c++ - 使用什么代码更好地进行运算符重载

c++ - 将按位和 C++ 重载为非成员函数

c++ - 运算符 << 重载错误 - 未找到运算符

c++ - Qt:在 TreeView 中设置列

c++ - XSD 生成的解析器中的 gSOAP 替代方案

c++ - 在 debian linux 中使用 c 复制文件

C++:头文件中的模板正在摧毁我

C++:重复调用 system()