我有一个带有模板参数的函数,我知道它是几个不同元素类型的标准C ++容器的std::tuple
。
如何从中提取一个std::tuple
元素类型的类型?
例如,假设我有以下功能
template <typename TupOfCtrs>
void doStuff(const TupOfCtrs& tupOfCtrs) {
using TupOfElements = /*extract a tuple type by applying CtrT::value_type to each container in tupOfCtrs and combining the results into an std::tuple*/;
MyHelperClass<TupOfElements> helper;
}
我知道这是这样叫的:
std::list<Foo> l {/*...*/};
std::vector<Bar> v {/*...*/};
std::deque<Baz> d {/*...*/};
auto tup = std::make_tuple(l, v, d);
在这种情况下,我希望将TupOfElements
帮助器类型定义为std::tuple<Foo, Bar, Baz>
。
请注意,我不需要实际创建元组,只需获取其类型。
如何实现,可能使用Boost::Fusion库?
答案 0 :(得分:4)
如果没有像这样的Boost Fusion,你甚至可以以更简单的方式做到这一点:
// Template which takes one type argument:
template <typename Tuple> struct TupOfValueTypes;
// Only provide a definition for this template for std::tuple arguments:
// (i.e. the domain of this template metafunction is any std::tuple)
template <typename ... Ts>
struct TupOfValueTypes<std::tuple<Ts...> > {
// This definition is only valid, if all types in the tuple have a
// value_type type member, i.e. the metafunction returns a type only
// if all types of the members in the std::tuple have a value_type
// type member, and a std::tuple can be constructed from these:
using type = std::tuple<typename Ts::value_type...>;
};
template <typename TupOfCtrs>
void doStuff(const TupOfCtrs& tupOfCtrs) {
using TupOfElements = typename TupOfValueTypes<TupOfCtrs>::type;
// ...
}
但是,明确地为doStuff
指定std::tuple
当然更容易:
template <typename ... Ts>
void doStuff(const std::tuple<Ts...> & tupOfCtrs) {
using TupOfElements = std::tuple<typename Ts::value_type...>;
// ...
}
PS:另请注意,在许多情况下,如果您只需要一个类型列表,std::tuple
类就是一种过度杀伤,并且可能会略微损害编译时间。就个人而言,我总是使用简单的TypeList
结构:
template <typename ... Ts> struct TypeList
{ using type = TypeList<Ts...>; };
答案 1 :(得分:4)
如果您希望doStuff
选择std::tuple
,请明确说明:
template <class... Ts>
void doStuff(std::tuple<Ts...> const& tupOfCtr) { ... }
一旦你有了参数包,只需要取出value_type
:
template <class... Ts>
void doStuff(std::tuple<Ts...> const& tupOfCtr)
{
using value_tuple = std::tuple<typename Ts::value_type...>;
// ...
}