C ++ 11:在传值参数的初始化中转换构造函数和转换函数之间的歧义?

时间:2012-03-12 02:33:11

标签: c++ c++11 copy-constructor implicit-conversion language-lawyer

#include <iostream>
using namespace std;

struct Y;

struct X
{
    X(const Y&) { cout << "converting constructor" << endl; }
};

struct Y
{
    operator X() { cout << "conversion function" << endl; }
};

void f(X x) {}

int main()
{
    Y y;
    f(y);
}

在上面,转换函数被我的编译器(gcc 4.6.1)优先用于转换构造函数,但是在标准中它声明:

  

用户定义的转化仅适用于明确的

在这种情况下似乎存在歧义。任何人都可以解释这个矛盾吗?

我原本以为不能编译。几年前我也非常肯定Scott Meyers写了这个具体的例子,并说它不会编译。我错过了什么?

2 个答案:

答案 0 :(得分:5)

因为X构造函数需要const参数,所以它更喜欢运算符。如果删除X构造函数中的const,则编译器会抱怨模糊性。如果有多个具有参考参数的函数,则首选具有最宽松const限定的函数。

一个好的答案here

答案 1 :(得分:1)

此处没有歧义,唯一有效的转换由转换功能提供。
请注意,y 不是const ,您的转换构造函数需要const参数。

如果您的转换构造函数采用非const引用,则会有歧义。

<强> Online Sample:

#include <iostream>
using namespace std;

struct Y;

struct X
{
    X(Y&) { cout << "converting constructor" << endl; }

};

struct Y
{
    operator X() { cout << "conversion function" << endl; }
};

void f(X x) {}

int main()
{
    Y y;
    f(y);
    return 0;  
}

<强>输出:

  

prog.cpp:在成员函数'Y :: operator X()'中:
  prog.cpp:13:警告:函数返回非空格中没有return语句   prog.cpp:在函数'int main()'中:
  prog.cpp:21:错误:从'Y'到'X'的转换是模糊的   prog.cpp:13:注意:候选者是:Y :: operator X()
  prog.cpp:8:注意:X :: X(Y&amp;)