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

实现带非默认构造函数的类型键值可变参数模板映射

实现基于类型键的实例映射结构

问题描述

需要实现一个以类型为键的映射结构TypeToValMap,将指定类型的对象关联到对应Processor实例,支持通过类型直接获取实例并调用方法。预期使用方式如下:

// 前置定义
struct A;
struct B;

template<class T>
struct Processor {
    Processor(T foo);
    void SomeFunction();
};

// 预期用法
int main(){
    A a;
    B b;

    TypeToValMap<KeyValue<A, Processor<A>>,
                 KeyValue<B, Processor<B>>> myMap{{a}, {b}}; // 用a、b构造对应Processor
    
    myMap.get<A>().SomeFunction(); // 获取Processor<A>实例并调用方法
    myMap.get<B>().SomeFunction(); // 获取Processor<B>实例并调用方法
}

尝试使用std::variant或std::any存储实例未成功,询问是否可实现该结构。

实现方案

完全可以实现该结构,核心是利用编译期模板元编程绑定类型与实例,无需依赖std::variant或std::any,直接将每个KeyValue实例作为TypeToValMap的成员存储,通过编译期查找定位对应类型的成员。

完整实现代码

#include <utility>
#include <type_traits>

// 补全前置定义的结构体
struct A {};
struct B {};

template<class T>
struct Processor {
    // 实现构造函数:接收T类型对象初始化
    Processor(T foo) {}
    // 实现成员方法
    void SomeFunction() {}
};

// KeyValue:绑定键类型与值类型的结构体
template<class Key, class Value>
struct KeyValue{
    using key_type = Key;
    using value_type = Value;
    value_type val;

    // 转发构造函数:接收初始化Value的参数
    template<typename... CtorArgs>
    explicit KeyValue(CtorArgs&&... args) 
        : val(std::forward<CtorArgs>(args)...) {}
};

// TypeToValMap核心实现:基于类型的实例映射
template<typename... KeyVals>
struct TypeToValMap : private KeyVals... {
    // 构造函数:转发参数到每个KeyValue成员
    template<typename... Args>
    explicit TypeToValMap(Args&&... args) 
        : KeyVals(std::forward<Args>(args))... {}

    // 通过键类型T获取对应Value实例
    template<class T>
    constexpr auto& get() {
        // 编译期找到对应Key为T的KeyValue成员
        using TargetKV = KeyValue<T, typename GetValueByKey<T, KeyVals...>::type>;
        return static_cast<TargetKV&>(*this).val;
    }

private:
    // 元函数:编译期通过键类型查找对应Value类型
    template<class TargetKey, class KeyVal, class... Rest>
    struct GetValueByKey {
        using type = typename std::conditional_t<
            std::is_same_v<TargetKey, typename KeyVal::key_type>,
            typename KeyVal::value_type,
            typename GetValueByKey<TargetKey, Rest...>::type
        >;
    };

    // 递归终止条件:未找到对应键时触发编译错误
    template<class TargetKey>
    struct GetValueByKey<TargetKey> {
        static_assert(!std::is_same_v<TargetKey, TargetKey>, 
                      "Error: Target type not found in TypeToValMap");
    };
};

关键说明

  1. KeyValue结构:

    • 绑定键类型key_type与值类型value_type,存储值实例val
    • 提供转发构造函数,支持传递任意参数初始化value_type(比如示例中的A/B对象)
  2. TypeToValMap结构:

    • 私有继承所有KeyValue模板参数,使每个KeyValue成为类的成员,避免命名冲突
    • 构造函数通过参数转发,将每个初始化参数传递给对应KeyValue的构造函数
    • get<T>()方法:
      • 利用GetValueByKey元函数在编译期定位对应T的KeyValue类型
      • 通过static_cast转换到目标KeyValue成员,返回其内部的val实例
      • 若传入未注册的类型键,编译期会触发断言报错,确保类型安全
  3. 性能与安全性:

    • 所有类型匹配和实例查找都在编译期完成,无运行时开销
    • 强类型检查,避免运行时类型转换错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 10:03:33