c++ - 删除导致模棱两可的过载的转换?
问题描述
我们的代码是多平台的。我使用 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
吗?
解决方案
最简单的解决方案是将运算符 bool 声明为explicit
. 用作 a或中的条件if
,将调用显式运算符,但对于函数调用的隐式转换将被忽略。while
for
推荐阅读
- javascript - 使用 AJV 针对 JSON 模式验证 API 响应
- vba - 停止 VBA 代码并取消或取消它已经处理的所有内容?
- c - C - 使用 CBC(密码块链接)模式的 OpenSSL 加密
- oracle - 是否可以在不使用包的情况下在 PL/SQL 的单个程序中编写函数和过程?
- reactjs - React JS make async call without componentdidmount()
- jquery - JQuery 选项卡不会加载
- python - Index - Match using Pandas
- apache - 如何使用 mod_auth_openidc 将用户声明传递给上游层?
- c - 从 C 中的文件读取,“%*lf”如何工作?
- java - Android: Is it possible to use Google Maps API on emulator?