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

如何构建可追加类型的constexpr TypeVector并实现存储类型反向查询

问题根因

你当前的实现思路本质是做了编译期类型擦除:将类型映射为唯一const char*值的同时,丢失了值和类型的静态关联,C++模板系统无法自动完成值到类型的反向推导,因此才需要手动编写特化,也无法支持模板实例的批量适配。

最优解决方案

采用无类型擦除的编译期类型列表实现,所有类型信息直接保存在TypeVector的模板参数中,完全避免反向映射的问题,无需任何手动特化:

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

// 类型标签工具,C++20可直接用std::type_identity,低版本可自行实现
template <typename T>
struct type_identity {
    using type = T;
};

template <typename... Ts>
struct TypeVector {
    // 当前容器存储的类型数量
    static constexpr size_t size = sizeof...(Ts);

    // 获取指定下标对应的类型标签
    template <size_t I>
    constexpr auto get() const noexcept {
        return type_identity<std::tuple_element_t<I, std::tuple<Ts...>>>{};
    }

    // 追加类型,返回新的TypeVector实例
    template <typename T>
    constexpr auto push_back() const noexcept {
        return TypeVector<Ts..., T>{};
    }

    // 删除指定下标类型,返回新的TypeVector实例
    template <size_t I>
    constexpr auto erase() const noexcept {
        return []<size_t... Is>(std::index_sequence<Is...>) {
            auto pick_type = []<size_t J>(std::integral_constant<size_t, J>) {
                if constexpr (J < I) return type_identity<std::tuple_element_t<J, std::tuple<Ts...>>>{};
                else return type_identity<std::tuple_element_t<J+1, std::tuple<Ts...>>>{};
            };
            return TypeVector<typename decltype(pick_type(std::integral_constant<size_t, Is>{}))::type...>{};
        }(std::make_index_sequence<sizeof...(Ts)-1>{});
    }
};

// 反向获取类型工具,无需任何手动特化
template <typename T>
struct retrieve_type;

template <typename T>
struct retrieve_type<type_identity<T>> {
    using type = T;
};

template <typename T>
using retrieve_type_t = typename retrieve_type<T>::type;

使用示例

和你给出的预期伪代码完全对齐,天然支持任意模板实例化类型:

// 测试用模板类,无需做任何额外适配
template <typename T>
struct SomeTemplateClass {};

consteval auto build_vector() {
    TypeVector<> x;
    auto x1 = x.push_back<int>();
    auto x2 = x1.push_back<float>();
    // 直接追加模板实例化类型即可
    auto x3 = x2.push_back<SomeTemplateClass<double>>();
    return x3;
}

static constexpr auto my_vector = build_vector();

// 直接获取对应位置类型
retrieve_type_t<decltype(my_vector.get<0>())> some_variable = 0; // 等价于int some_variable = 0;
retrieve_type_t<decltype(my_vector.get<1>())> some_variable2 = 0.0f; // 等价于float some_variable2 = 0.0f;
retrieve_type_t<decltype(my_vector.get<2>())> some_variable3{}; // 等价于SomeTemplateClass<double> some_variable3{};

方案优势

  • 零手动特化成本:自动支持所有C++类型,包括任意深度的模板实例化类型
  • 纯编译期操作:无任何运行时开销
  • 兼容性好:仅依赖C20标准特性,无需第三方库。如果需要兼容C17,仅需将consteval改为constexpr,调整部分参数包展开语法即可。
  • 可扩展性强:可以很方便的追加插入、排序、遍历等编译期类型操作,也可以直接替换为Boost.Mp11等成熟元编程库的mp_list容器,内置了所有常用的类型列表操作能力。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 18:15:03