[英]Get variadic template variadic template parameter variadic parameters
是。
假设我有一个包含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)};
工作用法示例:
#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`!
通过部分特化,您可以将模板专精分割为模板和参数,这就是上述方法的工作原理。
模板模板参数不是真正的类型参数,是用于指定模板的参数。 这意味着你通过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不是类型,是模板。 但第二种是类型(是模板的实例)。
也就是说,检查你的问题:你所谓的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;
当然,这不是您的实现的完全解决方案,您需要将概念扩展到多个类型列表(正如您的问题所示)。 我提供的是了解问题及其解决方案的指南。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.