多个转换运算符导致赋值运算符不明确 [英] Multiple conversion operators causing assignment operator ambiguity

查看:158
本文介绍了多个转换运算符导致赋值运算符不明确的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用一些旧代码,以前的开发人员之一在其中创建了一个Guid(全局唯一IDentifier)类,该类使用Microsoft的GUID结构作为成员变量(下面的成员"MS").为了便于在两者之间进行转换,在Guid.h中定义了以下两个转换/广播运算符:

I am working with some legacy code, where one of the previous developers created a Guid (Global Unique IDentifier) class that used Microsoft’s GUID struct as a member variable (member "MS" below). To allow easy conversion between the two, the following two conversion/casting operators were defined in Guid.h:

/// Returns a GUID structure
operator GUID() const
{
    return MS;
}

/// Returns a reference to a GUID structure
operator GUID&()
{
    return MS;
}

将代码库移至VS2019版本时,出现以下编译器错误:

On moving the codebase to a VS2019 build, I get the following compiler error:

错误C2593:'运算符='是不明确的C:\ Program Files(x86)\ Windows 套件\ 10 \ include \ 10.0.18362.0 \ shared \ guiddef.h(27):注意:可能是 '_GUID& _GUID :: operator =(_ GUID&))C:\ Program Files(x86)\ Windows 套件\ 10 \ include \ 10.0.18362.0 \ shared \ guiddef.h(27):注意:或
'_GUID& _GUID :: operator =(const _GUID&)'

error C2593: 'operator =' is ambiguous C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\shared\guiddef.h(27): note: could be '_GUID &_GUID::operator =(_GUID &&)' C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\shared\guiddef.h(27): note: or
'_GUID &_GUID::operator =(const _GUID &)'

我假设编译器变得更加严格(自VS2013开始),或者Microsoft使用第二个重载的GUID赋值运算符更新了其GUID定义.发生此错误的示例如下:

I’m assuming either the compiler has become more strict (since VS2013) or Microsoft updated their GUID definition with a second overloaded GUID assignment operator. An example of where this error is hit is as follows:

void GuidExample(Guid initial)
{
    GUID myGUID = initial;
}

我的理解是,在分配过程中,编译器将尝试使用我们提供的两个转换运算符之一将Guid转换为GUID.但是,它不知道要使用哪个转换运算符,因此也不知道要使用哪个赋值运算符.

My understanding is that during the assignment, the compiler will try to convert the Guid to a GUID using one of the two conversion operators we’ve supplied. However, it doesn’t know which one of our conversion operators to use, and therefore doesn’t know which assignment operator to use.

如果我注释掉这两个转换运算符中的任何一个,则不会出现任何编译器错误.通过引用返回将允许访问GUID MS,这是可以的,因为它仍然是公共成员.因此,如果必须对转换操作进行一个定义,则将使用参考版本.

If I comment out either of the two conversion operators, I don’t get any compiler errors. Return by reference will allow access to GUID MS, which is OK because it is a public member anyway. So If I have to go with one definition of the conversion operation, I will go with the reference version.

但是我的问题是,有没有办法既保留两个定义又避免歧义?

However my question is, is there a way to keep both definitions and avoid the ambiguity?

推荐答案

该错误告诉您编译器无法在复制分配和移动分配之间进行选择.所以你是对的,赋值运算符现在有两个重载,它们只是通常的重载.

The error tells you that the compiler cannot choose between copy-assignment and move-assignment. So you're right, there are now two overloads of the assignment operator, and they're just the usual ones.

编译器可能更加严格.从VS2015 Update 3开始,Visual C ++一直使用/permissive-加强规则.

The compiler might be more strict. Visual C++ has been tightening the rules with /permissive-, starting with VS2015 Update 3.

修复可能很简单:

/// 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&()之后可能甚至无法生存.

The idea here is that you don't want a GUID& reference to a temporary Guid object which might not even survive after the call to operator GUID&().

这篇关于多个转换运算符导致赋值运算符不明确的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆