我们的代码是多平台的。我使用MSVC,而我的同事使用Clang或GCC。
我们的一个类具有指针转换,该转换始终返回非nullptr
。我发现由于在布尔表达式中意外使用它而导致的问题,该表达式始终返回true
。因此,我删除了布尔转换运算符。
这对我来说效果很好(实际上在程序中显示了我们执行此操作的其他十个位置),但是由于模棱两可的重载,我的同事无法再编译。
这里是情况:
class Thingy
{
public:
operator const double * () const
{
return xyz;
}
operator bool () const = delete;
private:
double xyz[3];
};
void func(const double *d)
{
}
void func(unsigned int i)
{
}
int main()
{
Thingy a;
func(a);
}
在MSVC上,我期望会调用func(const double *d)
。但是,在GCC上,它失败如下:
<source>: In function 'int main()':
<source>:27:9: error: call of overloaded 'func(Thingy&)' is ambiguous
func(a);
^
<source>:16:6: note: candidate: 'void func(const double*)'
void func(const double *d)
^~~~
<source>:20:6: note: candidate: 'void func(unsigned int)'
void func(unsigned int i)
^~~~
Compiler returned: 1
如果您取出operator bool () const = delete;
,它在GCC上可以正常工作,但是您没有受到以下保护:
Thingy b /* = callSomeFunction()*/;
if (!b)
{
// whoops! never enters here! Would be nice for this to be a compiler error.
}
else
{
// do something with the valid Thingy
}
我们认为,在GCC / Clang上,歧义介于调用func(const double*)
与转换为const double*
与调用func(unsigned int)
与转换为bool
之间,即使转换到bool
的位置明显无效。
为什么会这样? MSVC为什么允许它?除了#ifdef _MSVC_VER
以外,还有什么方法可以达到预期的效果?
答案 0 :(得分:1)
最简单的解决方案是将操作符bool声明为explicit
。在if
,while
或for
中用作条件时,显式运算符将被调用,但在函数调用中进行隐式转换时将被忽略。