3

これはコンパイラのバグのように見えますが、ケースは非常に単純で、少し懐疑的であるため、確認を求めています。VS2010とVS2012の両方で再現可能。以下の例はコンパイルされません。このエラーが発生します:

エラー1エラーC2440:「型キャスト」:「ConvertibleToAny」から「OtherType<_Ty>」に変換できませんtest.cpp40

OtherType(ThisType &&)コンストラクターの上にmoveコンストラクターの位置を移動すると、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仕様の関連する段落を引用してください。これはすでにMicrosoftConnectにバグとして投稿されています。ここをクリックして開きます

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)のすべての1引数コンストラクターはOtherType、13.3.1.3のルールに従って過負荷解決に参加します。

13.3:2に続いて、intとmoveコンストラクターの両方が使用可能であり、13.3.2に従って実行可能であるため、単一の引数に対して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 に答える