【问题标题】:Which gets precedence when Converting Constructor as well as Conversion Operator are defined and why compilers differ this conversion?定义转换构造函数和转换运算符时哪个优先,为什么编译器会对此转换有所不同?
【发布时间】:2020-03-28 13:38:43
【问题描述】:

标准用简单的语言对Converting ConstructorConversion Operator的优先级做了什么说明?

另外,我可以看到,当我有 2 个类 myClassotherClass 并且我想将 otherClass 转换为 myClass 时,如下所示,转换运算符被调用为类 otherClass

myClass mc = otherclass();//creates temp for otherClass

这个行为在 gcc 和 MSVC 中是一样的。

但是当我执行以下操作时,上述编译器的这种行为是不同的-

otherClass oC;
myClass mc = oC;//for gcc (C++11): Ambiguous, for MSVC: calls myClass Conversion Constructor

所以,我的问题是为什么在第一种情况下从临时初始化与第二种情况不同?其次,为什么编译器在第二种情况下的行为会有所不同?

编辑:类定义为

#include <iostream>
using namespace std;

class otherClass;
class myClass {
      public:
          myClass(){}
          myClass(otherClass&) {
          cout << "called myClass's conversion constructor" << endl;
          }
};

class otherClass {
      public:
         operator myClass () {
             cout << "called otherClass's conversion operator" << endl;
             return myClass ();
         }
};

int main()
{
    otherClass oc;
    myClass mc = oc;
    myClass mc1 = otherClass();
    return 0;
}

【问题讨论】:

  • 后一个示例背后的正式代码(显然)在 g++ 和 msvc 之间提供了不同的结果,这对您的问题很有启发性。 IE。包括类源和驱动主要。 IE。 minimal reproducible example,无论您认为它多么微不足道,包括相同工具链的版本。
  • 显示代码。有几件事可能会影响这一点。
  • 那仍然不是minimal reproducible example。一个完整的例子有#includes、main 等。在这种情况下,最好有一些输出,这样我们就可以判断是否实际调用了转换构造函数或转换函数。
  • 更新了完整的代码 aschepler
  • myClass(otherClass&amp;) 应该是myClass(const otherClass&amp;),顺便说一句。这应该可以解决您的 gcc 运行所抱怨的歧义。

标签: c++ type-conversion


【解决方案1】:

在定义转换构造器和转换运算符时优先

都没有。

为什么编译器会在这种转换上有所不同?

如果转换顺序不明确,则程序格式错误。因此允许编译器不生成程序,并且需要诊断问题。故意允许这种模棱两可的转换将被视为语言扩展,但无论扩展如何都无法诊断将不符合标准。

如果转换顺序是明确的,并且没有其他原因导致程序格式错误,则拒绝编译它的编译器不符合标准。


编辑:关于添加的示例:myClass mc = oc 的转换确实模棱两可,程序格式错误。因此,行为差异的一个可能原因是允许它的编译器的语言扩展,或者是编译器错误。如果没有被诊断出来,那么编译器不符合标准。我建议禁用语言扩展。

myClass mc1 = otherClass() 格式正确,因为只有一个有效的转换候选者。转换构造函数不是一个有效的候选对象,因为对非 const 的左值引用不能绑定到右值。

【讨论】:

  • 谢谢 erorika。但是在临时转换为我的类的情况下,幕后会发生什么,从而促进两个编译器的相同行为。
  • 感谢 eerorika 提醒右值绑定。在 MSVC 中禁用语言扩展后,我可以看到与 gcc 一致的行为。
猜你喜欢
  • 2014-07-28
  • 2021-12-04
  • 2010-11-25
  • 2018-08-12
  • 2012-09-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-12
相关资源
最近更新 更多