是的,你可以用递归来做到这一点......事实上你或多或少地重新实现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);
两者都可以改进以获得更好的错误报告(虽然我使用了这两种技术,但我什至没有尝试编译这个示例代码)