我有一个包装器类,其行为应类似于指针。我已经超载operator T*
和operator bool
。布尔进行了一些额外的验证。我尝试在if中使用该对象,但我注意到调用了operator T*
而不是bool
。有人可以解释我为什么吗?是在标准中以某种方式指定的吗?我在MSVC,clang和gcc中测试了以下示例代码,它们都称为operator T*
。另外,从我在本页上看到的内容[https://en.cppreference.com/w/cpp/language/implicit_conversion),if应该尝试转换为bool
。
#include <stdio.h>
class MyClass
{
public:
MyClass(int i)
: m(i)
{}
operator bool() const
{
printf("operator bool()\n");
return m;
}
operator int* ()
{
printf("operator int* ()\n");
return &m;
}
private:
int m;
};
int main()
{
MyClass a(5);
MyClass b(0);
if (a)
printf("a is true\n");
else
printf("a is false\n");
if (b)
printf("b is true\n");
else
printf("b is false\n");
return 0;
}
PS:我也尝试过使用!!
和(bool)
,但它仍然调用operator int*()
。对于operator bool()
,我必须明确地调用它。
在类定义中,转换运算符operator bool
用限定符const
声明,但是if语句中使用的对象不是常量对象。
operator bool() const
^^^^^
{
printf("operator bool()\n");
return m;
}
删除限定符const
,将调用运算符operator bool
。
或声明转换运算符operator int *
,例如
operator const int* () const
{
printf("operator int* ()\n");
return &m;
}
并再次调用运算符operator bool
。
[当运算符具有限定符const并应用于非常数对象时,则需要再进行一次转换,即资格转换。
此外,您甚至可以将运算符声明为显式的。例如
explicit operator bool()
{
printf("operator bool()\n");
return m;
}
如果您想看看如何得出弗拉德(正确)的答案,则过程大致上是
条件是一个可以在上下文中转换为布尔值的表达式
[if
属于隐式转换-特别要注意的是
如果调用的函数或运算符有多个重载,则在从T1到每个可用的T2构造隐式转换序列之后,重载解决规则将决定编译哪个重载。
然后在转换顺序下,第三步“零或一个标准转换序列”出现在用户定义的转换之后,并且该步骤可以将指针转换为bool。
这意味着两个用户定义的转换运算符对于该顺序的中间步骤都是可行的。最后,
描述如何选择最佳可行功能。由于两个运算符在转换序列中间步骤的上下文中都是可行的,因此after发生的额外的指针到布尔转换不会对过载排名产生影响。
具体来说,排名是基于以下事实:一个运算符要求对其隐式第一(Overload resolution)参数进行const限定,而另一个则不需要。这就是为什么同一运算符的一对const和非const限定的重载将总是选择其限定与所调用的对象最匹配的重载。
我想您可以在标准中找到特定的措辞。或this
但是我想说的是您要的是this proposal