1

次のコードを検討してください。

template <class Scalar, class Array, class Tuple>
class Test {};

は でArrayありstd::arrayTuplestd::tupleです。Typesこのクラスでは、多くの SFINAE を使用し、型の完全なリストを含むという大きなタプルを作成したいと考えています。これにより、可変長リストを使用していくつかの条件をテストできます。

したがって、課題は、次の動作を持つ型を作成することです。もしも:

  • Scalar = int
  • Array = std::array<double, 3>
  • Tuple = std::tuple<char, float, std::string>

それで:

  • Types = std::tuple<int, double, double, double, char, float, std::string>

ScalarArrayおよびの内部データを連結したものですTuple

どうやってするか ?

4

2 に答える 2

2

これはうまくいくようです:

template<typename T1, typename T2>
struct concat_tuples;

template<typename... T1, typename... T2>
struct concat_tuples<std::tuple<T1...>, std::tuple<T2...>>
{
    using type = std::tuple<T1..., T2...>;
}; 

// n_tuple<int, 3>::type == std::tuple<int, int, int>
template<typename T, size_t n>
struct n_tuple;

template<typename T>
struct n_tuple<T, 0> 
{
    using type = std::tuple<>;
};

template<typename T, size_t n>
struct n_tuple
{
    using type = typename concat_tuples<
                    typename n_tuple<T, n-1>::type, 
                    std::tuple<T>
                >::type;
};

template <class Scalar, class Array, class Tuple>
struct Test;

template <class Scalar,  typename T, size_t n, typename... Ts>
struct Test<Scalar, std::array<T, n>, std::tuple<Ts...>>
{
    using type = typename concat_tuples<
                    typename concat_tuples<
                        std::tuple<Scalar>, 
                        typename n_tuple<T, n>::type
                    >::type, 
                    std::tuple<Ts...>
                >::type;
};

ライブデモはこちら.

于 2013-08-15T22:33:58.310 に答える
1

部分的な特殊化を使用して型を推測し、Xeo のtuple_catコメントを使用してそれらをまとめます ( Live at Coliru :

template <typename ArrayType, std::size_t ArraySize, typename... Fields>
struct ArrayTuple : ArrayTuple<ArrayType, ArraySize-1, ArrayType, Fields...> {};
template <typename ArrayType, typename... Fields>
struct ArrayTuple<ArrayType, 0, Fields...> {
    using type = std::tuple<Fields...>;
};

template <typename, typename, typename> class Test;

template <typename Scalar, typename ArrayType, std::size_t ArraySize, typename... Fields>
class Test<Scalar, std::array<ArrayType, ArraySize>, std::tuple<Fields...>> {
public:
    // Modified tuple_cat code from Xeo's comment:
    using Tuple = std::tuple<Fields...>;
    using Types = decltype(
      std::tuple_cat(std::tuple<Scalar>(),
                     typename ArrayTuple<ArrayType, ArraySize>::type(),
                     std::declval<Tuple>()));
};
于 2013-08-15T22:37:21.593 に答える