C++ 删除导致不明确重载的转换?

C++ 删除导致不明确重载的转换?,c++,visual-c++,C++,Visual C++,我们的代码是多平台的。我使用MSVC,我的同事使用Clang或GCC 我们的一个类有一个指针转换,它总是返回非nullptr。我发现一个问题,因为在布尔表达式中意外使用了它,它总是返回true。因此,我删除了布尔转换运算符 这对我来说非常有效(事实上,在我们的程序中还有十个地方我们也在做这项工作),但是我的同事们由于不明确的重载而无法再编译了 情况如下: classthingy { 公众: 运算符常量双*()常量 { 返回xyz; } 运算符bool()const=delete; 私人: 双xy

我们的代码是多平台的。我使用MSVC,我的同事使用Clang或GCC

我们的一个类有一个指针转换,它总是返回非
nullptr
。我发现一个问题,因为在布尔表达式中意外使用了它,它总是返回
true
。因此,我删除了布尔转换运算符

这对我来说非常有效(事实上,在我们的程序中还有十个地方我们也在做这项工作),但是我的同事们由于不明确的重载而无法再编译了

情况如下:

classthingy
{
公众:
运算符常量双*()常量
{
返回xyz;
}
运算符bool()const=delete;
私人:
双xyz[3];
};
无效函数(常数双*d)
{
}
void func(无符号整数i)
{
}
int main()
{
一件事;
func(a);
}
在MSVC上,调用了
func(constdouble*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
我们认为,在GCC/Clang上,在调用
func(const double*)
并将其转换为
const double*
和调用
func(unsigned int)
并将其转换为
bool
,两者之间存在歧义,即使到
bool
的转换显然无效


为什么会这样?MSVC为什么允许这样做?除了可能的
\ifdef\u MSVC\u VER
之外,我们还有什么方法可以获得所需的效果?

最简单的解决方案是将操作符bool声明为
显式
。将显式运算符用作
if
while
for
中的条件,但对于函数调用的隐式转换,将忽略显式运算符


我认为他们希望在尝试隐式转换时得到一个错误bool@M.M如果我正确理解了这个问题,他们希望在If语句中使用对象时出错,而If语句不是隐式转换,它调用显式运算符。这在用作
的操作数时也会出错
&&
|
,或作为
的第一个操作数:
,这对于这种类型是一件好事。理想的情况是隐式和显式转换都会出错,但显式至少比目前给我们提供了更多的保护。你能详细说明一下“期望的效果”是什么吗?当你说“它在gcc上运行良好”如果未删除bool转换运算符,您是否确认实际调用了
func
的正确重载?@M.M期望的效果是
Thingy x;if(x)
Thingy y=someFunction();bool-okSoFar=y;okSoFar |=someOtherValidation();
都会导致编译器错误,如果有一个函数重载同时使用了
双精度*
和可以从
双精度*
转换的东西(例如
无符号int
),编译器会毫无怨言地使用
双精度*
重载。@JohnDrouhard是的,godbolt.org说
函数(双常量*)
就是所谓的。(我不知道共享链接持续多长时间,但是:)