如果我有一个元组类型不同的元组,如
std::tuple<T0, T1, T2, ...>
如何获取元素类型的索引?
template<class T, class Tuple>
struct Index
{
enum {value = ?;}
};
感谢。
答案 0 :(得分:19)
template <class T, class Tuple>
struct Index;
template <class T, class... Types>
struct Index<T, std::tuple<T, Types...>> {
static const std::size_t value = 0;
};
template <class T, class U, class... Types>
struct Index<T, std::tuple<U, Types...>> {
static const std::size_t value = 1 + Index<T, std::tuple<Types...>>::value;
};
此实现返回给定类型第一次出现的索引。请求一个不在元组中的类型的索引会导致编译错误(并且会产生相当丑陋的错误)。
答案 1 :(得分:1)
template< size_t I, typename T, typename Tuple_t>
constexpr size_t index_in_tuple_fn(){
static_assert(I < std::tuple_size<Tuple_t>::value,"The element is not in the tuple");
typedef typename std::tuple_element<I,Tuple_t>::type el;
if constexpr(std::is_same<T,el>::value ){
return I;
}else{
return index_in_tuple_fn<I+1,T,Tuple_t>();
}
}
template<typename T, typename Tuple_t>
struct index_in_tuple{
static constexpr size_t value = index_in_tuple_fn<0,T,Tuple_t>();
};
上面的示例避免了生成大量的子元组,这在您为大型元组调用index_in_tuple
时使编译失败(内存不足)
答案 2 :(得分:0)
另一个使用折叠表达式。 找不到时,还会将值设置为-1。
template <class X, class Tuple>
class Idx;
template <class X, class... T>
class Idx<X, std::tuple<T...>> {
template <std::size_t... idx>
static constexpr ssize_t find_idx(std::index_sequence<idx...>) {
return -1 + ((std::is_same<X, T>::value ? idx + 1 : 0) + ...);
}
public:
static constexpr ssize_t value = find_idx(std::index_sequence_for<T...>{});
};