在课堂上移动构造函数的位置/顺序很重要?模板转换操作符与移动构造函数一起使用

时间:2012-09-11 07:29:59

标签: c++ visual-studio-2010 visual-c++ c++11 visual-studio-2012

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

  

错误1错误C2440:'type cast':无法转换   '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的错误click here to open it发布。

1 个答案:

答案 0 :(得分: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())

这是 direct-initialization (8.5:15),因此(8.5:16)OtherType的所有单参数构造函数参与13.3中规则的重载解析。 1.3。

遵循13.3:2,int和移动构造函数都可用并且每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的意图显然是在这种情况下应考虑显式转换函数;因此,再次出现重载解析应该失败。