You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何创建可索引访问的类型元组?早期C++版本替代pack indexing方案

如何在C++26之前实现可按索引访问的类型元组?

请问如何创建一个无需借助pack indexing即可按索引访问的类型元组?已知在C++26中可通过pack indexing实现如下简单类型元组:

template <typename... Ts>
struct type_tuple {
    template <unsigned Index>
    using get = Ts...[Index];
};

using T = type_tuple<int, float, double>::get<1>; // float

那么该如何在更早的C++版本中实现相同的功能?

C++11/14 实现方案

方法1:递归模板提取

通过递归展开模板参数包,逐步定位到目标索引对应的类型:

// 辅助递归模板
template <unsigned Index, typename Head, typename... Tail>
struct type_at {
    using type = typename type_at<Index - 1, Tail...>::type;
};

// 递归终止条件:索引为0时返回第一个类型
template <typename Head, typename... Tail>
struct type_at<0, Head, Tail...> {
    using type = Head;
};

template <typename... Ts>
struct type_tuple {
    template <unsigned Index>
    using get = typename type_at<Index, Ts...>::type;
};

// 使用示例
using T = type_tuple<int, float, double>::get<1>; // 得到float类型

方法2:复用标准库std::tuple_element

如果允许依赖标准库,直接借助std::tuple_element可以快速实现,代码更简洁:

#include <tuple>

template <typename... Ts>
struct type_tuple {
    template <unsigned Index>
    using get = typename std::tuple_element<Index, std::tuple<Ts...>>::type;
};

// 使用示例
using T = type_tuple<int, float, double>::get<1>; // 得到float类型

C++17 实现方案

C++17的折叠表达式和编译期特性可以让我们摆脱递归,用更直观的方式实现:

#include <type_traits>
#include <utility>

template <unsigned Index, typename... Ts>
constexpr auto pick_type(std::index_sequence<Is...>) -> std::type_identity<
    decltype((std::declval<Ts>(), ... , (Is == Index ? std::declval<Ts>() : std::declval<Ts>())))
>;

template <typename... Ts>
struct type_tuple {
    template <unsigned Index>
    using get = decltype(pick_type<Index, Ts...>(std::make_index_sequence<sizeof...(Ts)>{}))::type;
};

// 使用示例
using T = type_tuple<int, float, double>::get<1>; // 得到float类型

或者另一种更简洁的写法:

#include <type_traits>
#include <tuple>
#include <utility>

template <unsigned Index, typename... Ts>
using get_type_t = std::tuple_element_t<
    []<unsigned... Is>(std::index_sequence<Is...>) {
        return (Is == Index ? Is : 0) + ...;
    }(std::make_index_sequence<sizeof...(Ts)>{}),
    std::tuple<Ts...>
>;

template <typename... Ts>
struct type_tuple {
    template <unsigned Index>
    using get = get_type_t<Index, Ts...>;
};

内容的提问来源于stack exchange,提问作者HeliumHydride

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 07:57:17