通过模糊转换运算符引用绑定

时间:2015-12-06 16:35:42

标签: c++ visual-studio c++11 c++14 copy-initialization

#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编译好并打印&#34;运算符const CL2&amp;&#34;。根据标准必须如何正确?
在我看来,将CL1转换为const CL2&amp;在复制初始化上下文中(作为cl2对象的直接初始化的一部分)。我看过n4296草稿,[over.match.copy]:

  

假设“cv1 T”是要初始化的对象的类型,   使用T类类型,候选函数选择如下:
   - T的转换构造函数(12.3.1)是候选者   功能。
   - 初始化表达式的类型是a时   类类型“cv S”,S的非显式转换函数及其   考虑基类。初始化临时绑定时   到参数是类型的构造函数的第一个参数   “引用可能的cv-qualified T”并调用构造函数   在直接初始化的上下文中使用单个参数   对象类型为“cv2 T”,显式转换函数也是如此   考虑。那些没有隐藏在S中并产生一个类型的类型   cv-unqualified version与T的类型相同或是派生类   它是候选功能。 返回的转化功能   “引用X”返回左值或x值,具体取决于类型   因此,X的类型的引用被认为是为此产生X.   选择候选函数的过程。

即。两个转换运算符都被认为是返回CL2和const CL2(不仅仅是没有const的CL2)并且它仍然需要解决,哪个转换更好:CL2 - &gt; const CL2&amp;或const CL2 - &gt; const CL2&amp ;.第二种情况似乎更合适。在这种情况下是否应考虑更好的资格转换?或两种情况都是身份转换?我无法在标准

中找到它

1 个答案:

答案 0 :(得分:4)

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

  

- 上下文是用户定义转换的初始化(见8.5,   13.3.1.5和13.3.1.6)以及从F1的返回类型到目的地类型的标准转换序列(即,类型   正在初始化的实体)是比转换序列更好的转换序列   标准转换序列从返回类型F2到。{   目的地类型。

......或(1.5):

  

- 上下文是直接转换函数的初始化   引用绑定(13.3.1.6)对函数类型的引用,[...]

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

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

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