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

C++如何按索引获取type_list指定位置类型(优先非递归实现)

非递归实现type_list按索引取类型

不需要递归实现,也不需要绕路用std::is_same做类型匹配,直接通过参数包展开就能实现编译期定位的typeAt能力,完全不依赖std::tuple,适配传递type_list临时实例的使用场景。

实现代码

首先定义基础的type_list结构:

template<typename...>
struct type_list {};

核心type_at实现,无任何递归模板实例化,编译开销极低:

#include <type_traits>

template<size_t I, typename List>
struct type_at;

template<size_t I, typename... Ts>
struct type_at<I, type_list<Ts...>> {
private:
    // 核心技巧:通过参数包构造类型标签指针数组,按下标直接定位目标类型
    static constexpr auto pick() {
        using void_ptr_arr = void*[];
        return static_cast<std::type_identity<Ts>*>(
            void_ptr_arr{ static_cast<void*>(static_cast<std::type_identity<Ts>*>(nullptr))... }[I]
        );
    }
public:
    using type = typename decltype(pick())::type;
};

// 便捷使用别名
template<size_t I, typename List>
using type_at_t = typename type_at<I, List>::type;

使用示例

完全符合预期的调用形式:

using L = type_list<int, char, float, double>;
// 取索引为2的类型,推导结果为float
using T = type_at_t<2, L>;
// 类型校验
static_assert(std::is_same_v<T, float>);

// 适配传type_list临时实例的场景
template<typename... Ts>
void f(type_list<Ts...>) {
    // 函数内部可任意获取指定位置的类型
    using LastType = type_at_t<sizeof...(Ts) - 1, type_list<Ts...>>;
}

int main() {
    f(L{}); // 直接传入type_list临时实例即可
}

方案说明

  • 你提到的std::index_sequence遍历+std::is_same匹配std::integral_constant的方案可以实现功能,但属于冗余实现:不需要做类型相等判断,甚至不需要依赖std::index_sequence,上面给出的数组下标定位写法是目前编译开销最低的非递归实现,长类型列表场景下编译速度优势明显。
  • 整个实现没有递归逻辑,完全依赖标准的参数包展开规则,没有引入std::tuple相关依赖,type_list是独立的轻量结构,不会带来额外编译负担。
  • 所有逻辑都在编译期完成,没有任何运行时开销,pick函数仅用于类型推导,不会生成实际的运行时代码。

内容的提问来源于stack exchange,提问作者Chris G.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 03:33:08