【问题标题】:C++11: Ambiguity between Converting Constructor and Conversion Function in Initialization of Pass-By-Value Parameter?C ++ 11:在传递值参数的初始化中转换构造函数和转换函数之间的歧义?
【发布时间】:2012-03-28 11:58:26
【问题描述】:
#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);
}

在上面的 conversion function 由我的编译器(gcc 4.6.1)优先于 converting constructor,但是在标准中它指出: p>

用户定义的转换仅适用于明确的地方

在这种情况下似乎存在歧义。谁能解释一下这个矛盾?

我原以为以上内容无法编译。我也很确定几年前 Scott Meyers 写过这个具体的例子,并说它不会编译。我错过了什么?

【问题讨论】:

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


    【解决方案1】:

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

    一个很好的答案here

    【讨论】:

      【解决方案2】:

      这里没有歧义,唯一有效的转换是由转换函数提供的。
      请注意,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:警告:函数中没有返回语句返回非 void
      prog.cpp:在函数“int main()”中:
      prog.cpp:21:错误:从“Y”到“X”的转换不明确
      prog.cpp:13:注意:候选人是:Y::operator X()
      prog.cpp:8: 注意:X::X(Y&)

      【讨论】:

      • 顺便说一句,代码示例中没有具体的 c++11。即使在 c++03 中代码也有效。
      • 拒绝投票的原因是什么?请在您投反对票时说明您认为错误的原因,如果您想不出任何逻辑/技术理由来证明投反对票的合理性,请认为自己没有资格投反对票。
      • 对不起。我认为我拒绝投票的原因已经在接受的答案中给出。构造函数可以被转换使用。但这不是首选。
      • @JohannesSchaub-litb:是的,它可以使用,但这里没有歧义,const 或非 const 版本的顺序被选中的定义很好。不确定我选择的单词是否在答案中表明其他任何内容。
      猜你喜欢
      • 1970-01-01
      • 2017-02-13
      • 1970-01-01
      • 1970-01-01
      • 2020-06-12
      • 2015-04-08
      • 1970-01-01
      • 1970-01-01
      • 2020-09-23
      相关资源
      最近更新 更多