我希望做这样的事情:
template<typename ...T> struct foo
{
bar<0 /*to index through types in pack*/ ,T...>::type var1;
bar<1 /*to index through types in pack*/ ,T...>::type var2;
...
}
但我如何定义bar
?这样做不会出现递归技术。
我想要一种通用技术,以便我可以从类型包中键入任何特定类型,而不仅仅是示例中显示的两种类型。
答案 0 :(得分:5)
#include <iostream>
#include <typeinfo>
template<class T, class T2, class... Args>
class C
{
public:
typedef T type1;
typedef T2 type2;
};
int main()
{
typedef C<int, double, int, float> c;
std::cout << typeid(c::type1).name() << " " << typeid(c::type2).name() << std::endl;
}
或者像这样的事情。
#include <iostream>
#include <typeinfo>
template<int N, class T, class... Args>
struct expand
{
public:
typedef typename expand<N - 1, Args...>::type type;
};
template<class T, class... Args>
struct expand<1, T, Args...>
{
public:
typedef T type;
};
template<class... Args>
class argsExpander
{
public:
typedef typename expand<1, Args...>::type type1;
typedef typename expand<2, Args...>::type type2;
};
template<class... Args>
class C
{
public:
typename argsExpander<Args...>::type1 var1;
typename argsExpander<Args...>::type2 var2;
};
int main()
{
C<int, double, int, float> c;
std::cout << typeid(c.var1).name() << " " << typeid(c.var2).name() << std::endl;
}
http://liveworkspace.org/code/7de289f128e86eb6006f576cbaf98991
答案 1 :(得分:1)
是的,您可以通过递归执行此操作...事实上,您或多或少地重新实施std::tuple
(并隐式std::get
)。
努力工作来自访问会员,因为除非您手动命名,否则无法呼叫var1
,var2
等。
template <typename... TypeList> struct foo;
template <typename Head, typename... Tail>
struct foo<Head, Tail...>: public foo<Tail...>
{
Head var;
};
我在这里使用了继承,但是组合(使用foo<Tail...> tail
成员)也可以。
现在,如果您的类型是唯一的,您可以按类型访问该成员...
// this overload if VarType is the first
template <typename VarType, typename... FooTail>
VarType& foo_get(foo<VarType, FooTail...>& f)
{
return f.var;
}
// this overload to walk down to foo's parent
template <typename VarType, typename FooHead, typename... FooTail>
VarType& foo_get(foo<FooHead, FooTail...>& foo)
{
return foo_get<VarType>(static_cast<foo<FooTail...>>(f));
}
// call like:
// int &x = foo_get<int>(my_foo_object);
或者您可以按位置访问:
template <int N, typename... TypeList> struct GetHelper;
template <typename Head, typename... Tail>
struct GetHelper<0, Head, Tail...>
{
static Head& get(foo<Head, Tail...> &f) { return f.var; }
};
template <int N, typename Head, typename... Tail>
struct GetHelper<N, Head, Tail...>: public GetHelper<N-1, Tail...>
{};
template <int N, typename... TypeList>
auto foo_get(foo<TypeList...> &f)
-> GetHelper<N, TypeList...>::get(*static_cast<foo<TypeList...>*>(0))
{
return GetHelper<N, TypeList...>::get(f)
}
// call like:
// int &x = foo_get<2>(my_foo_object);
这两个都可以改进以获得更好的错误报告(虽然我已经使用了这两种技术,但我甚至没有尝试编译这个示例代码)
答案 2 :(得分:1)
如果我理解你的问题,你想要实现类似于std :: tuple的东西:
我认为元组以这种方式实现:
template <class T>
class tuple
{
T mem;
};
template <class T, class... REST>
class tuple : tuple<REST...>
{
T mem;
};
答案 3 :(得分:1)
只需 使用 std :: tuple,因为@Xeo会继续发表评论。它很方便,完全符合您的要求。
引用:
为什么不使用std::tuple<T...>
?
访问元素std::get<I>(tup)
和
类型为std::tuple_element<I, std::tuple<T...>>::type