static_cast 到 int 时关于删除 bool 运算符的错误

Error about deleted bool operator when static_cast to int

在执行 static_cast<int> 时,我收到有关已删除的 bool() 运算符的投诉:

main.cpp:15:35: error: use of deleted function 'J::operator bool()'
     j = static_cast<int>(*this) + 1;
                               ^

可能我在这里遗漏了一些明显的东西,但我不明白为什么它会尝试 运行 布尔转换:

#include <iostream>

struct J {
    int j;
    J (int j) : j (j) {}

    operator bool() = delete;

    explicit operator int() const {
        if (j > 304) { std::cout << "Out of range\n"; }
        return j;
    }

    J& operator++ () {
        j = static_cast<int>(*this) + 1;
        return *this;
    }
};

int main() {
    J b {1020};
    ++b;
}

简而言之,将 bool 运算符重载更改为以下之一:

explicit operator bool() = delete; // Prevent implicit conversion (int to bool)
operator bool() const = delete;    // Non-const had higher priority for resolution

这是关于两件事。隐式整数转换和函数解析顺序。


这似乎基本上是典型的 C++ 函数解析。让我们回忆一下:

class A {
public:
  void foo() { cout << "non-const" << endl; }
  void foo() const { cout << "const" << endl; }
};

int main() {
  A a1;
  a1.foo(); // prints "non-const"
  const A a2;
  a2.foo(); // prints "const"
  return 0;
}

如果非const可用,它的优先级高于const。

回到你的例子,让我们把事情弄清楚,将 bool cast 运算符更改为 non-const int cast。

explicit operator int() = delete; // Instead of "operator bool() = delete;"

这样,还是失败,原因同上。由于 operator++ 是非常量,所以 this 是非常量,所以 static_cast<int>(*this) 被解析为非常量 operator int。但是它被删除了,所以编译器会抱怨。因此,如果我们没有删除这个非 const 版本,它就会用 const 版本解析并正常工作。

那么 operator bool() = delete; 呢?此函数未使用 explicit 声明,因此 int 将隐式尝试转换为 bool。所以它在到达常量之前用删除的解决了。