Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/158.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;隐式类型转换的构造函数_C++_Visual Studio_Type Conversion_Explicit Constructor - Fatal编程技术网

C++ C++;隐式类型转换的构造函数

C++ C++;隐式类型转换的构造函数,c++,visual-studio,type-conversion,explicit-constructor,C++,Visual Studio,Type Conversion,Explicit Constructor,我有以下代码: class Type2 { public: Type2(const Type1 & type); Type2(int); const Type2 & operator=(const Type2 & type2); //.... }; ... Type1 t1(13); Type2 t2(4); t2=t1; 据我所知,Type2的单参数构造函数(每个构造函数没有显式关键字)应该意味着任何Type1对象或int值都可以隐式转换为Ty

我有以下代码:

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

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

  t2=t1;
据我所知,Type2的单参数构造函数(每个构造函数没有显式关键字)应该意味着任何Type1对象或int值都可以隐式转换为Type2对象

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

..错误C2679:二进制“=”:无运算符 找到接受右侧操作数的 类型为“Type1”(或没有 可接受的转换)


似乎微软VisualStudio坚持t2=t1;必须将赋值运算符与lhs=Type2和rhs=Type1匹配。为什么它不能隐式地将rhs强制转换为t2,然后用Type2=Type2操作符进行复制呢?

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

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

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

此代码:

#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;
}
现在,如果我删除
操作符Fred()
之后的
常量
,它就会编译并使用转换构造函数。如果我还从
main
中的
b
声明中删除了
const
,那么它将首选转换运算符

这一切都符合过载解决规则。当gcc不能在转换运算符和转换构造函数之间进行选择时,它会生成适当的模糊误差


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

这段代码在VS2010中对我来说很好。我知道原因。因为我的Type1有一个转换操作符:类Type1{operator Type2()};我可以结束一个我自己找到答案的问题吗?@JavaMan:你可以(也应该)回答你自己的问题。@JavaMan:甚至可以将你自己的答案标记为已接受的答案,让社区知道这个问题现在已经解决了。很有意思。这在GCC中编译得很好。是的,甚至VS2010有时也会编译。但我必须弄清楚确切的时间。这是标准的模棱两可的情况,编译器无法判断应该使用哪种转换。如果Type2得到了Type2=Type1的赋值运算符,VS2010就会编译。顺便说一下,我测试这些的原因是我想知道编译器是否能识别这些模糊的情况(如我的C++书所指出的)@ VJO:OP的代码片段(S)组合,再加上虚拟函数体。
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