指针类型运算符 VS 常量布尔运算符优先级


#include <cstdint>
#include <iostream>
struct a_struct {
int64_t* le_int;
bool not_ok;
a_struct() : le_int{ new int64_t(0) }, not_ok{ false } {}
~a_struct() { delete le_int; }
operator bool() const {
return !not_ok;
}
operator int64_t* () {
return le_int;
}
};
int main(int argc, char** argv) {
a_struct s;
s.not_ok = true;
if (!s)//<-
std::cout << "o no." << std::endl;
else if (s.not_ok)
std::cout << "waddu heck?" << std::endl;
return 0;
}

在此示例中,!s分辨率优先使用int64_t*()运算符而不是 constbool()运算符。

为什么?

这是重载解析的"通过转换函数初始化"情况:http://eel.is/c++draft/over.match.conv

这两个转换函数都是候选函数,因为两者都是非显式的,并且它们的返回类型可隐式转换为bool。然后,使用对象表达式s作为参数,转换函数的隐含对象参数作为参数来执行重载解析。隐含对象参数的类型为Tcv&,其中T是类。

T&绑定到T比将T const&绑定到T更好。这是对隐式转换序列进行排名的规则之一。http://eel.is/c++draft/over.ics.rank#3.2.6

请注意,有一个涉及转换函数返回类型的仲裁规则。只有在每个参数的隐式转换序列的排序未能产生最佳可行函数时,才会考虑这种决胜规则,因为每个参数的隐式转换序列既不比另一个函数的相应参数的隐式转换序列更好也不差。因此,仅当两个转换函数具有相同的 cv 限定(导致隐含对象参数的隐式转换序列相同)时,才会达到决胜局。http://eel.is/c++draft/over.match.best#general-2.2

由于您的对象 s 不是常量,因此它更喜欢调用类型强制转换运算符的非常量方式。因此,从布尔类型转换运算符中删除 const 可以解决问题。

最新更新