[英]Multiple conversion operators causing assignment operator ambiguity
我正在处理一些遗留代码,其中一位以前的开发人员创建了一个 Guid(全局唯一标识符)类,该类使用 Microsoft 的 GUID 结构作为成员变量(下面的成员“MS”)。 为了方便两者之间的转换,在 Guid.h 中定义了以下两个转换/转换运算符:
/// Returns a GUID structure
operator GUID() const
{
return MS;
}
/// Returns a reference to a GUID structure
operator GUID&()
{
return MS;
}
在将代码库移动到 VS2019 版本时,我收到以下编译器错误:
错误 C2593:'operator =' 不明确 C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.18362.0\\shared\\guiddef.h(27): 注意:可能是 '_GUID &_GUID::operator =( _GUID &&)' C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.18362.0\\shared\\guiddef.h(27):注意:或
'_GUID &_GUID::operator =(const _GUID &)'
我假设编译器变得更加严格(自 VS2013 起),或者 Microsoft 使用第二个重载的 GUID 赋值运算符更新了他们的 GUID 定义。 出现此错误的示例如下:
void GuidExample(Guid initial)
{
GUID myGUID = initial;
}
我的理解是,在赋值期间,编译器将尝试使用我们提供的两个转换运算符之一将 Guid 转换为 GUID。 但是,它不知道要使用哪一个转换运算符,因此也不知道要使用哪个赋值运算符。
如果我注释掉这两个转换运算符中的任何一个,则不会出现任何编译器错误。 通过引用返回将允许访问 GUID MS,这是可以的,因为它无论如何都是公共成员。 因此,如果我必须使用转换操作的一个定义,我将使用参考版本。
但是我的问题是,有没有办法保留两个定义并避免歧义?
更新:最小可重现示例。 这将在 VS2013 中构建,而不会在 VS2019 中构建,显示我之前提到的“'operator =' 不明确”错误。
#include <guiddef.h>
class Guid
{
public:
union
{
char Data[16];
GUID MS;
struct
{
int Q1;
int Q2;
};
};
Guid()
{
Q1 = 0;
Q2 = 0;
}
/// Returns a GUID structure
operator GUID() const
{
return MS;
}
/// Returns a reference to a GUID structure
operator GUID& ()
{
return MS;
}
};
GUID winGUID;
void testAssign(Guid myGuid)
{
winGUID = myGuid; //This causes ambiguity
GUID anotherWinGUID = myGuid; //This does not
}
int main()
{
Guid a;
testAssign(a);
return 0;
}
该错误告诉您编译器无法在复制赋值和移动赋值之间进行选择。 所以你是对的,现在有两个赋值运算符的重载,它们只是常见的。
编译器可能更严格。 从 VS2015 Update 3 开始,Visual C++ 一直在使用/permissive-
收紧规则。
修复可能很简单:
/// Returns a GUID structure
operator GUID() const
{
return MS;
}
/// Returns a reference to a GUID structure
operator GUID&() & // << the trailing & is a reference-qualification.
{
return MS;
}
这里的想法是,您不希望GUID&
引用临时Guid
对象,该对象在调用operator GUID&()
后甚至可能无法生存。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.