7

Aパラメータパックでタイプを見つけようとしています:

template <int I, typename A, typename B, typename ...C>
struct index_of
{
  static constexpr int const value =
    std::is_same<A, B>::value ? I : index_of<I + 1, A, C...>::value;
};

template <int I, typename A, typename B>
struct index_of<I, A, B>
{
  static constexpr int const value =
    std::is_same<A, B>::value ? I : -1;
};

これは機能しているIようですが、デフォルトのパラメーターにしたい非型パラメーターを削除できませんが、最後のパラメーターパックのためにそのようにすることはできません。を削除/非表示Iにして、メタ関数をよりユーザーフレンドリーにする方法は?

4

3 に答える 3

6

この実装を名前空間で非表示にし、デフォルト パラメータの例で実装を呼び出す別のクラスを使用できます。

namespace detail
{
    // your code as it is in the question
}

template <typename A, typename... B>
struct index_of
{
    static int const value = detail::index_of<0, A, B...>::value;
};

編集

彼のコメントで、DyP はIエイリアスを使用してデフォルトにするより簡単な方法を提案しています

template <typename A, typename... B>
using index_of = detail::index_of<0, A, B...>;
于 2013-07-24T21:21:47.173 に答える
3
template <typename A, typename B, typename... C>
struct index_of
{
  static constexpr int const value =
    std::is_same<A, B>{}
    ? 0
    : (index_of<A, C...>::value >= 0) ? 1+index_of<A, C...>::value : -1;
};

template <typename A, typename B>
struct index_of<A, B>
{
  static constexpr int const value = std::is_same<A, B>{} -1;
};

は からへstd::is_same<A, B>{} -1の変換を使用することに注意してください。boolint


から派生することでより良いintegral_constant

template <typename A, typename B, typename... C>
struct index_of
  : std::integral_constant
    < int,
        std::is_same<A, B>{}
      ? 0
      : (index_of<A, C...>{} == -1 ? -1 : 1+index_of<A, C...>{})
    >
{};

template <typename A, typename B>
struct index_of<A, B>
  : std::integral_constant < int, std::is_same<A, B>{} -1 >
{};

タイプが見つからない場合に戻る必要がない-1場合: (誰かがstatic_assertここにかなりの診断メッセージを組み込む方法を知っている場合は、コメント/編集をいただければ幸いです)

template <typename A, typename B, typename... C>
struct index_of
  : std::integral_constant < std::size_t,
                             std::is_same<A, B>{} ? 0 : 1+index_of<A, C...>{} >
{};

template <typename A, typename B>
struct index_of<A, B>
  : std::integral_constant<std::size_t, 0>
{
    constexpr operator std::size_t() const
    {
        return   std::is_same<A, B>{}
               ? 0
               : throw std::invalid_argument("Type not found!");
    }
};
于 2013-07-24T21:43:07.403 に答える