#include <iostream>
using namespace std;

struct CL2
{
    CL2(){}
    CL2(const CL2&){}
};

CL2 cl2;

struct CL1
{
    CL1(){}
    operator CL2&(){cout<<"operator CL2&"; return cl2;}
    operator const CL2&(){cout<<"operator const CL2&"; return cl2;}
};

CL1 cl1;

int main()
{
    CL1 cl1;
    CL2 cl2 (cl1);
}

clang和gcc都给出了模棱两可的转换运算符,但是Visual Studio可以编译并打印“operator const CL2&”。根据标准应该如何正确?
我不理解,CL1到const CL2&的转换是在复制初始化上下文中进行的(作为cl2对象直接初始化的一部分)。我看过n4296草稿,[over.match.copy]:



IE。这两个转换运算符都被视为返回CL2和const CL2(不仅是没有const的CL2),还有待解决,哪种转换更好:CL2-> const CL2&或const CL2-> const CL2&。第二种情况似乎更合适。在这种情况下是否应考虑进行更好的资格转换?还是两种情况都是身份转换?我在标准版中找不到

最佳答案

由于两个转换运算符都具有相同的签名,因此,一个优先于另一个的唯一方法是应用[over.match.best]/(1.4)…



…或(1.5):



显然,两者都不适用,因此存在歧义。消除歧义的可能方法:

operator CL2&();
operator const CL2&() const;

Demo;在这里,隐式对象参数的前一个过载的初始标准转换顺序按照[over.ics.rank]/(3.2.6)更好,而[over.match.best]/(1.3)是决定性的。

10-01 08:36