获取可变参数模板的可变参数模板参数

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 的 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)};  

2
1)TTupleTypeHolder是一个模板,而不是一个类型。 2)您无法访问A(您传递了一个没有参数的模板,因此没有参数可以推断)。 - dyp
请展示一个使用示例(TupleMaker的预期用法示例)。 - dyp
@DyP:添加了一个用法示例。 Nawaz:我知道,我只是想展示我尝试过的(但没有成功)。 - Vittorio Romeo
1
+1 for the title, if nothing else (but interesting question, too). 如果没有其他内容,标题加一分(但问题也很有趣)。 - Angew is no longer proud of SO
1
需要更多的可变参数。 - Yakk - Adam Nevraumont
显示剩余5条评论
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() {}

主模板需要两种类型,因为你正在传递类型。 TupleTypeHolder<int,char> 是一种类型,是模板的特化,而不是模板本身。然而,模板模板参数以模板作为参数(而不是类型),例如:

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

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

使用部分特化,您可以将模板特化拆分为模板和参数,这就是上述内容的工作原理。


太棒了!我甚至不知道你能使用部分模板特化传递两个可变参数类型包的技巧,因为在主模板类型上有一个限制,可变参数必须在末尾,编译器不允许两个包。我受益匪浅! - user955279
我感觉我本应该变得非常有见地,但是半路上我反而睡着了。+1 - Lightness Races in Orbit

2

模板-模板参数并不是真正的类型参数,而是用于指定模板的参数。这意味着通过模板-模板参数传递的不是类型,而是模板本身:

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不是一种类型,而是模板。但第二个则是一种类型(是该模板的实例)。
也就是说,请检查您的问题:您所谓的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;

当然,这并不是解决您实现的确切方法,您需要将概念扩展到多个类型列表(正如您的问题所显示的)。我提供的是了解问题及其解决方案的指南。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接