使用static_cast<int>时触发已删除bool()运算符错误的技术问询
为什么
static_cast<int>(*this)会触发已删除的operator bool()? 嘿,这个问题其实是C++转换运算符的const限定和重载解析规则在搞鬼,我来给你拆解清楚:
问题的核心原因
你代码里的explicit operator int()是带const限定的,但operator++里的*this是非const的对象。当编译器处理static_cast<int>(*this)时,它会优先寻找匹配非const对象的转换运算符——可惜你没提供非const版本的int转换。
这时候编译器不会直接放弃,它会尝试其他可能的转换路径:operator bool()虽然被你删除了,但它是**非const**的(你没给它加const修饰),所以编译器会把它当作候选,结果就触发了“使用已删除函数”的错误。
两种快速修复方案
方案1:给operator int()去掉const限定(或者新增非const版本)
如果你的转换操作不需要保证对象不被修改,直接去掉const是最简单的:
explicit operator int() { // 移除const修饰 if (j > 304) { std::cout << "Out of range\n"; } return j; }
要是你想保留const版本的兼容性,可以同时新增一个非const版本,内部复用const版本的逻辑:
explicit operator int() const { if (j > 304) { std::cout << "Out of range\n"; } return j; } explicit operator int() { // 转成const引用后调用const版本 return static_cast<const J&>(*this); }
方案2:在operator++中先把*this转成const引用
如果你不想修改转换运算符的const属性,也可以在operator++里主动把*this转换成const J&,让编译器匹配到const版本的int转换:
J& operator++ () { j = static_cast<int>(static_cast<const J&>(*this)) + 1; return *this; }
修复后的验证代码
这里以方案1为例,给你完整的可运行代码:
#include <iostream> struct J { int j; J (int j) : j (j) {} operator bool() = delete; explicit operator int() { 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; std::cout << b.j << std::endl; // 会输出1021,同时打印"Out of range" }
内容的提问来源于stack exchange,提问作者HostileFork says dont trust SE
相关产品推荐
相关产品推荐

