2

たとえば、私はタイプを持っています

template<unsigned i> struct Element;

template struct Element<0> {typedef int Type};
template struct Element<1> {typedef float Type};
template struct Element<2> {typedef double Type};

static const int COUNT = 3;

次のようなタイプのタプルを作成したい

std::tuple<Element<0>::Type, Element<1>::Type, Element<2>::Type>

COUNT が定数であるが常に 3 ではない場合、どうすればよいですか?

4

2 に答える 2

2

これが可能なアプローチです。クラス テンプレートの定義を考えると、次のようになります。

template<unsigned i> struct Element;

template<> struct Element<0> { typedef int type; };
template<> struct Element<1> { typedef float type; };
template<> struct Element<2> { typedef double type; };

通常のインデックス フレームワークを利用して、次のように記述できます。

#include <tuple>

namespace detail
{
    template<int... Is>
    struct seq { };

    template<int N, int... Is>
    struct gen_seq : gen_seq<N - 1, N - 1, Is...> { };

    template<int... Is>
    struct gen_seq<0, Is...> : seq<Is...> { };

    template<template<unsigned int> class TT, int... Is>
    std::tuple<typename TT<Is>::type...> make_tuple_over(seq<Is...>);
}

template<template<unsigned int> class TT, int N>
using MakeTupleOver = 
    decltype(detail::make_tuple_over<TT>(detail::gen_seq<N>()));

そして、これはあなたのプログラムでそれを使用する方法です:

#include <type_traits> // For std::is_same

int main()
{
    static_assert(
        std::is_same<
            MakeTupleOver<Element, 3>, 
            std::tuple<int, float, double>
        >::value, "!");
}

これが実際のです。

于 2013-07-11T20:36:57.833 に答える
2

基本的に 2 つの方法があり、アイデアのみが異なります:インデックス((機能的な) 可変個引数テンプレートが利用可能な場合)、またはタプルを手動で構築する (Visual C++ がある場合)。

指標:

template<unsigned... Is> struct seq{};
template<unsigned I, unsigned... Is>
struct gen_seq : gen_seq<I-1, I-1, Is...>{};
template<unsigned... Is>
struct gen_seq<0, Is...>{ using type = seq<Is...>; };

template<unsigned N, template<unsigned> class TT,
  class Seq = typename gen_seq<N>::type>
struct tuple_over{};

template<unsigned N, template<unsigned> class TT, unsigned... Is>
struct tuple_over<N, TT, seq<Is...>>{
  using type = std::tuple<typename TT<Is>::type...>;
};

手動再帰:

template<unsigned N, template<unsigned> class TT, class TupleAcc = std::tuple<>>
struct tuple_over{
  using tt_type = typename TT<N-1>::type;
  // since we're going from high to low index,
  // prepend the new type, so the order is correct
  using cat_type = decltype(std::tuple_cat(std::declval<std::tuple<tt_type>>(), std::declval<TupleAcc>()));
  using type = typename tuple_over<N-1, TT, cat_type>::type;
};

template<template<unsigned> class TT, class Tuple>
struct tuple_over<0, TT, Tuple>{ using type = Tuple; }

使用法は両方のバージョンで同じです。

using result = tuple_over<COUNT, Element>::type;

インデックスの実例。
手動再帰の実例。

于 2013-07-11T20:40:39.213 に答える