【问题标题】:C++ Constructor for Implicit Type Conversion用于隐式类型转换的 C++ 构造函数
【发布时间】:2011-09-18 01:55:26
【问题描述】:

我有这些代码:

class Type2 {
public:
  Type2(const Type1 & type);
  Type2(int);
const Type2 & operator=(const Type2 & type2);
//....
};

...
  Type1 t1(13);
  Type2 t2(4);

  t2=t1;

据我了解,Type2 的 1 参数构造函数每个都没有 explicit 关键字应该意味着任何 Type1 对象或 int 值都可以隐式转换为 Type2 对象。

但是在最后一行 t2=t1;,MS Visual Studio 给了我这个编译错误:

....错误 C2679:二进制“=”:无运算符 发现它需要一个右手操作数 'Type1' 类型(或没有 可接受的转换)....

似乎 MS Visual Studio 坚持 t2=t1; 必须匹配具有 lhs=Type2 和 rhs=Type1 的赋值运算符。为什么不能将 rhs 隐式转换为 t2 然后使用 Type2=Type2 运算符进行复制?

【问题讨论】:

  • 这段代码在 VS2010 中编译得很好。
  • 我知道为什么。因为我的Type1有一个转换运算符:class Type1 { operator Type2() };
  • 我可以关闭我自己找到答案的问题吗?
  • @JavaMan:你可以(也应该)回答你自己的问题。
  • @JavaMan:甚至可以将您自己的答案标记为已接受的答案,让社区知道此问题现已解决。

标签: c++ visual-studio type-conversion explicit-constructor


【解决方案1】:

我找到了答案。因为我的 Type1 有一个转换运算符

    class Type1 {
    public:
        Type1 (int );
        operator  Type2() ;//casting to Type2

    ....
    };

这就是所谓的“双向隐式转换”

【讨论】:

  • 有趣。这在 GCC 中编译得很好。
  • 是的,即使 VS2010 有时也会编译。但我必须弄清楚确切的时间。这是编译器无法判断应该使用哪种转换的标准模棱两可的情况。恕我直言,它们应该会产生编译时错误。
  • 如果 Type2 得到 Type2=Type1 的赋值运算符,VS2010 会编译。顺便说一句,我测试所有这些的原因是我想弄清楚编译器是否可以识别这些模棱两可的情况(正如我的 C++ 书中所指出的那样)
  • @VJo:OP 的代码 sn-p(s) 组合,加上虚拟函数体。
【解决方案2】:

这段代码:

#include <iostream>

using ::std::cerr;

class Barney;

class Fred {
 public:
   Fred() { }
   Fred(const Barney &b) { cerr << "Using conversion constructor.\n"; }
};

class Barney {
 public:
   Barney() { }
   operator Fred() const { cerr << "Using conversion operator.\n"; return Fred(); }
};

int main(int argc, const char *argv[])
{
   const Barney b;
   Fred f;
   f = b;
   return 0;
}

在 gcc 4.6 中生成此错误:

g++ -O3 -Wall fred.cpp -o a.out
fred.cpp: In function ‘int main(int, const char**)’:
fred.cpp:23:8: error: conversion from ‘const Barney’ to ‘const Fred’ is ambiguous
fred.cpp:21:17: note: candidates are:
fred.cpp:16:4: note: Barney::operator Fred() const
fred.cpp:10:4: note: Fred::Fred(const Barney&)
fred.cpp:7:7: error:   initializing argument 1 of ‘Fred& Fred::operator=(const Fred&)’

Compilation exited abnormally with code 1 at Sun Jun 19 04:13:53

现在,如果我在operator Fred() 之后删除const,它就会编译并使用转换构造函数。如果我还从mainb 的声明中删除const,则它更喜欢转换运算符。

这一切都符合重载决议规则。当 gcc 无法在转换运算符和转换构造函数之间进行选择时,gcc 会生成相应的歧义错误。

我注意到在您提供的示例中,转换运算符缺少const。这意味着永远不会出现使用转换运算符或转换构造函数不明确的情况。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-11-02
    • 1970-01-01
    • 2019-05-14
    • 2018-11-05
    • 2014-02-24
    • 1970-01-01
    • 2016-02-22
    • 1970-01-01
    相关资源
    最近更新 更多