3

这看起来像一个编译器错误,但案例是如此简单我有点怀疑,所以我正在寻找一个确认。VS2010 和 VS2012 均可重现。下面的示例无法编译。给出此错误:

错误 1 ​​错误 C2440:“类型转换”:无法从“ConvertibleToAny”转换为“OtherType<_Ty>”test.cpp 40

如果将移动构造函数的位置移动到构造函数OtherType(ThisType &&)之上OtherType( int ),它会突然编译。

#include "stdafx.h"
#include <string>

using namespace std;

template<class _Ty>
struct OtherType
{
  typedef OtherType<_Ty>  ThisType;

  OtherType()
  { 
  }

  OtherType( int )
  { 
  }

  // The move constructor
  OtherType(ThisType && )
  {
  }
};

struct ConvertibleToAny
{    
  template <class AnyType>
  operator AnyType()
  {
    return AnyType();
  }
};

int _tmain(int argc, _TCHAR* argv[])
{

  (OtherType<wstring>) ConvertibleToAny();

    return 0;
}

这是一个错误还是这是预期的行为?如果符合预期,请引用 C++11 规范中的相关段落。我已经在 Microsoft Connect 上将此作为错误发布,请单击此处将其打开

4

1 回答 1

6

你的表情

(OtherType<wstring>) ConvertibleToAny()

是从临时用户定义类型到用户定义类型的一元显式转换 (5.4),按照 5.4:4 解释为static_cast

static_cast<OtherType<wstring>>(ConvertibleToAny())

每个 5.2.9:4 具有初始化临时变量的有效性t

OtherType<wstring> t(ConvertibleToAny())

这是直接初始化(8.5:15),因此 (8.5:16) 根据 13.3.1.3 中的规则,所有单参数构造函数都OtherType参与重载决议。

在 13.3:2 之后,theint和 move 构造函数都可用并且根据 13.3.2 是可行的,因此对于单个参数,我们有两个可能的隐式转换序列 (13.3.3.1):

ConvertibleToAny [temporary] -> int
ConvertibleToAny [temporary] -> OtherType<wstring> &&

在 13.3.3.1.2 之后,这些序列之间没有排序,因此没有最佳可行函数,重载决议失败 (13.3:3),并且程序格式错误。


如果转换函数 (12.3.2) 是explicit(12.3.2:2) 则只考虑直接初始化。尽管隐式转换序列 (13.3.3.1) 是隐式转换 (4:3),因此涉及复制初始化,但 12.3.2:2 示例中标准的意图显然是在这种情况下应考虑显式转换函数; 因此,重载解决方案似乎再次失败。

于 2012-09-11T12:07:15.153 回答