3

テンプレート メタ プログラミングでは、戻り値の型に SFINAE を使用して、特定のテンプレート メンバー関数を選択できます。

 template<int N> struct A {
   int sum() const noexcept
   { return _sum<N-1>(); }
 private:
   int _data[N];
   template<int I> typename std::enable_if< I,int>::type _sum() const noexcept
   { return _sum<I-1>() + _data[I]; }
   template<int I> typename std::enable_if<!I,int>::type _sum() const noexcept
   { return _data[I]; }
};

ただし、この例のように、問題の関数 (_sum()上記の例) に自動検出された戻り値の型がある場合、これは機能しません。_func()

template<int N> class A
{
   /* ... */
private:
  // how to make SFINAE work for _func() ?
  template<int I, typename BinaryOp, typename UnaryFunc>
  auto _func(BinaryOp op, UnaryFunc f) const noexcept -> decltype(f(_data[0]))
  { return op(_func<I-1>(op,f),f(_data[I])); }
};

ここで SFINAE を取得するには、他に何ができますか?

4

1 に答える 1

1

David Rodríguez - dribeas に従って、次のコードは意図したとおりに機能しました。

template<int N> class A
{
  int min_abs() const noexcept
  {
    return _func<N-1>([](int x, int y)->int { return std::min(x,y); },
                      [](int x)->int { return std::abs(x); });
  }
private:
  int _data[N];

  template<int I, typename BinaryOp, typename UnaryFunc>
  auto _func(BinaryOp op, UnaryFunc f) const noexcept
    -> typename std::enable_if< I>,decltype(f(_data[0]))>::type
  { return op(_func<I-1>(op,f),f(_data[I])); }

  template<int I, typename BinaryOp, typename UnaryFunc>
  auto _func(BinaryOp op, UnaryFunc f) const noexcept
    -> typename std::enable_if<!I>,decltype(f(_data[0]))>::type
  { return f(_data[I]); }
};

厳密に言えば、二項演算子opが正しい型を返すことも確認する必要があります。答えを簡単かつ簡潔にするために、読者が理解できるようにします...

于 2013-01-29T18:22:12.113 に答える