3

はい。

typedef を保持する単純な可変個引数構造体があるとします。

template<typename... TArgs> struct TupleTypeHolder {
    using TupleType = std::tuple<TArgs*...>;
};

TupleTypeHolder<something>テンプレート パラメーターとして別のクラスに渡し、その typedef を取得します。

私の試みはすべてコンパイルされません。

// None of these is valid
template<template<typename...> class TTupleTypeHolder> struct TupleMaker {
     using MyTupleType = TTupleTypeHolder::TupleType; // Not valid
     using MyTupleType = typename TTupleTypeHolder::TupleType; // Not valid
};

 template<template<typename... A> class TTupleTypeHolder> struct TupleMaker2 {
     // A is not a valid name here
     using MyTupleType = TTupleTypeHolder<A...>::TupleType; // Not valid
     using MyTupleType = typename TTupleTypeHolder<A...>::TupleType; // Not valid
};

前述のクラスをテンプレートの可変個引数テンプレート パラメーターとして使用するクラスから可変個引数テンプレート クラスの可変個引数テンプレート パラメーター (この場合はTupleTypeHolder's ) を使用する方法はありますか?TArgs...


使用例:

template<typename... TArgs> struct TupleTypeHolder {
    using TupleType = std::tuple<TArgs*...>;
};

template<typename... TArgs> static int getSomeValue() { ... }

template<??? T1, ??? T2> class TupleMaker 
{ 
    std::pair<int, int> someValues;

    using TupleType1 = T1::TupleType;
    using TupleType2 = T2::TupleType;

    TupleMaker() : someValues{getSomeValue<T1's TArgs...>(), 
                             getSomeValue<T2's TArgs...>()} { }
};

class MyTupleMaker : TupleMaker<TupleTypeHolder<int, char>, 
                                TupleTypeHolder<int, float>> 
{ };

MyTupleMaker::TupleType1 tuple1{new int(1), new char('a')};  
MyTupleMaker::TupleType2 tuple1{new int(35), new float(12.f)};  
4

2 に答える 2

5

使用例:

#include <tuple>

template<typename... TArgs> struct TupleTypeHolder {
    using TupleType = std::tuple<TArgs*...>;
};

template<typename... TArgs> static int getSomeValue() { return 42; }

// primary template:
template<class T1, class T2>
struct TupleMaker;

// partial specialization:
template<template<class...> class TT1, template<class...> class TT2,
         class... T1, class... T2>
struct TupleMaker < TT1<T1...>, TT2<T2...> >
{ 
    std::pair<int, int> someValues;

    using TupleType1 = typename TT1<T1...>::TupleType;
    using TupleType2 = typename TT2<T2...>::TupleType;

    TupleMaker() : someValues{getSomeValue<T1...>(), 
                              getSomeValue<T2...>()} { }
};

struct MyTupleMaker : TupleMaker<TupleTypeHolder<int, char>, 
                                TupleTypeHolder<int, float>> 
{ };

MyTupleMaker::TupleType1 tuple1{new int(1), new char('a')};  
MyTupleMaker::TupleType2 tuple2{new int(35), new float(12.f)};  

int main() {}

型を渡すため、プライマリ テンプレートは 2 つの型を取ります。TupleTypeHolder<int, char>テンプレート自体ではなく、テンプレートの特殊化であるタイプです。ただし、テンプレートの template-parametersは、次のようにテンプレートを (型ではなく) 引数として受け取ります。

template<template<class...> class Foo>
struct Bar
{
    using type = Foo<int, double, char>;
};

Bar< std::tuple > b; // note: no template arguments for `std::tuple`!

部分的な特殊化を使用すると、テンプレートの特殊化をテンプレートとパラメーターに分割できます。これが上記の仕組みです。

于 2013-10-10T14:43:24.567 に答える
2

template-template パラメーターは実際には型パラメーターではなく、テンプレートを指定するパラメーターです。つまり、 template-template パラメーターを介して渡すものは型ではなく、テンプレートです。

template<template<typename> class TPARAM>
struct give_me_a_template
{
    using param = TPARAM; //Error TPARAM is not a type, is a template.
    using param_bool = TPARAM<bool>; //OK, thats a type
};

ご覧のとおり、TPARAM は型ではなくテンプレートであるため、最初のエイリアスは無効です。しかし、2 番目は型です (テンプレートのインスタンスです)。

とはいえ、問題を調べてくださいTupleTypeHolder。呼び出したものは、可変個引数テンプレートの型リストと見なすことができます。あなたの目標は、タイプリストで指定されたタイプのタプルを作成することですよね?

部分的な特殊化を使用して、タイプリストのコンテンツを抽出できます。

template<typename TupleTypeHolder>
struct tuple_maker;

template<typename... Ts>
struct tuple_maker<TupleTypeHolder<Ts...>>
{
    using tuple_type = std::tuple<Ts...>;
};

その使用例は次のとおりです。

using my_types = TupleTypeHolder<int,int,int>;
using my_tuple_type = typename tuple_maker<my_types>::tuple_type;

もちろん、これは実装の正確な解決策ではありません。概念を複数のタイプリストに拡張する必要があります(質問が示したように)。私が提供したのは、問題とその解決策を理解するためのガイドです。

于 2013-10-10T14:43:37.297 に答える