2

これがVS 2010で機能しないのはなぜですか

  typename std::enable_if<!std::has_trivial_destructor<Titem>::value, BOOL>::type
  Clear()
    {
        ...
    }

  typename std::enable_if<std::has_trivial_destructor<Titem>::value, BOOL>::type
  Clear()
    {
        ...
    }

テンプレートクラスの中にあります。

次のエラーが表示されます。

error C2039: 'type' : is not a member of 'std::tr1::enable_if<_Test,_Type>'

SFINAE エラーについて。どうやら置換失敗はエラーです。デストラクタ呼び出しを最適化するだけかもしれないことはわかっているので、これは本当に現実的なシナリオではありません。やっとSFINAEを理解できたと思っても、いざ使おうとするとうまくいきません。

いくつかのコメント (戻り値のみによるオーバーロードに関する懸念) に対応して、ダミー パラメーターの手法に変更しました。

これは機能します:

  template<typename U>
  BOOL _Clear(typename std::enable_if<!std::has_trivial_destructor<U>::value>::type *dummy = 0)
  {
     ...
  }

  template<typename U>
  BOOL _Clear(typename std::enable_if<std::has_trivial_destructor<U>::value>::type *dummy = 0)
  {
     ...
  }

  BOOL Clear()
  {
    return _Clear<Titem>();
  }

結論: テンプレートのメンバーでさえ、MSVC 2010 で SFINAE を実行するには、テンプレート化されたメンバー関数を強制する必要があります。

4

1 に答える 1

3

私自身、SFINAE の詳細の多くについて完全には確信が持てない人として、問題は関数がテンプレート化されていないことだとあえて言います。

試す

template<typename T = Titem>
typename std::enable_if<std::has_trivial_destructor<T>::value, BOOL>::type
Clear()
{
    ...
}

template<typename T = Titem>
typename std::enable_if<!std::has_trivial_destructor<T>::value, BOOL>::type
Clear()
{
    ...
}

編集: TitemMatthieu M. の提案に従って、デフォルトのパラメーターとして追加されました。

于 2012-12-18T08:12:29.527 に答える