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

如何在编译时从类型集合中获取对应整数值?

编译时类型-整数值映射的C17/C20实现

C++17 解决方案

C++17里可以通过模板变量特化实现编译时的类型到整数的映射,这种方式简单直接,代码量少:

#include <string>
#include <type_traits>

// 基础模板,默认值为0
template<typename T>
constexpr int TypeMap = 0;

// 为需要映射的类型逐一特化,指定对应整数值
template<> constexpr int TypeMap<int> = 1;
template<> constexpr int TypeMap<char> = 2;
template<> constexpr int TypeMap<double> = 4;
template<> constexpr int TypeMap<std::string> = 8;
template<> constexpr int TypeMap<const char*> = 8; // 适配字符串字面量类型

struct MyStructure {
    // 补充默认构造函数,满足main里直接创建对象的需求
    MyStructure() = default;
    MyStructure(char* d, int size) {}

    template<typename T>
    MyStructure& operator=(const T& arg) {
        // 用std::decay_t处理参数的const/引用等修饰,确保类型匹配
        type_ = TypeMap<std::decay_t<T>>;
        return *this;
    }

    int type_ = 0;
};

int main() {
    MyStructure myStruct;
    myStruct = 1;             // type_被设为1
    myStruct = 'a';           // type_被设为2
    myStruct = 3.14;          // type_被设为4
    myStruct = std::string("test"); // type_被设为8
    myStruct = "Hello world"; // type_被设为8
}

思路说明

  • 定义通用模板变量TypeMap,默认值为0;
  • 为每个需要映射的类型编写特化版本,指定对应的整数值;
  • 赋值运算符模板中,用std::decay_t去除参数类型的const、引用等修饰,确保能匹配到对应的特化模板,直接获取编译时确定的整数值赋值给type_。

C++20 解决方案

C++20带来了模板lambda、std::type_identity等新特性,可以把类型映射表集中管理,扩展性更好:

#include <string>
#include <type_traits>
#include <tuple>

struct MyStructure {
    MyStructure() = default;
    MyStructure(char* d, int size) {}

    // 编译时类型-值映射表,用tuple集中存储所有映射关系
    static constexpr auto type_map = std::make_tuple(
        std::pair(std::type_identity<int>{}, 1),
        std::pair(std::type_identity<char>{}, 2),
        std::pair(std::type_identity<double>{}, 4),
        std::pair(std::type_identity<std::string>{}, 8),
        std::pair(std::type_identity<const char*>{}, 8)
    );

    // 编译时查找函数,用模板lambda+折叠表达式遍历tuple
    template<typename T>
    static constexpr int find_type_value() {
        using TargetT = std::decay_t<T>;
        return [&]<std::size_t... I>(std::index_sequence<I...>) {
            // 遍历所有tuple元素,匹配类型后返回对应值
            return (... + (std::is_same_v<TargetT, typename std::tuple_element_t<I, decltype(type_map)>::first::type> 
                ? std::get<I>(type_map).second 
                : 0));
        }(std::make_index_sequence<std::tuple_size_v<decltype(type_map)>>{});
    }

    template<typename T>
    MyStructure& operator=(const T& arg) {
        type_ = find_type_value<T>();
        return *this;
    }

    int type_ = 0;
};

int main() {
    MyStructure myStruct;
    myStruct = 1;             // type_被设为1
    myStruct = 'a';           // type_被设为2
    myStruct = 3.14;          // type_被设为4
    myStruct = std::string("test"); // type_被设为8
    myStruct = "Hello world"; // type_被设为8
}

思路说明

  • 用std::type_identity包装类型,把所有类型-值的映射关系集中放在type_map这个constexpr tuple里;
  • 利用C++20的模板lambda和索引序列,在编译时遍历tuple,通过std::is_same_v匹配目标类型,找到对应的整数值;
  • 新增映射关系时,只需要在type_map里添加一对std::pair即可,无需额外编写模板特化,维护更方便。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 22:48:17