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

如何处理C++模板可变参数并将其包装为自定义容器实例

问题根源

编译报错由三处核心问题导致:

  1. std::get 类型参数使用错误
    你的m_Storage tuple存储的元素类型是MyContainer<StructA>、MyContainer<StructB>这类容器实例,不是StructA、StructB本身。你直接用std::get<OneStruct>(m_Storage)查找元素时,tuple中不存在OneStruct类型的元素,编译器匹配失败才会抛出类型不匹配的报错。
  2. 测试代码语法错误
    auto& tests = StructStorage <SA, SB, SC>(); 尝试用非const左值引用绑定临时对象,C++标准不支持这种操作,会触发编译错误。
  3. MyContainer::Contains方法逻辑错误
    std::map的operator[]在key不存在时会自动插入默认构造的元素,且m_Map[id]返回的是结构体实例,和m_Size整数比较没有意义,也会触发类型不匹配报错。

修正后的可运行代码

1. 修正MyContainer实现

#include <map>
#include <tuple>
#include <cstdint>

template<typename T_elem, typename T_int = uint64_t, T_int MAX_SIZE = 4096>
class MyContainer{
public:
    MyContainer() = default;
    ~MyContainer() = default;

    // 修正Contains逻辑:判断id是否存在于map中
    bool Contains(const T_int& id) const {
        return m_Map.find(id) != m_Map.end();
    }

    T_elem& operator[](const T_int& id) {
        return m_Map[id];
    }

    T_elem& Get(const T_int& id) {
        return operator[](id);
    }

private:
    std::map<T_int, T_elem> m_Map;
    T_int m_Size = 0;
};

2. 修正StructStorage实现

template<typename... LilStructs>
class StructStorage {
public:
    template<typename OneStruct>
    OneStruct& GetStruct(const uint64_t& id) {
        // 修正get的类型参数,指定获取MyContainer<OneStruct>类型的元素
        return std::get<MyContainer<OneStruct>>(m_Storage).Get(id);
    }

    template<typename OneStruct>
    bool ContainsStruct(const uint64_t& id) const {
        return std::get<MyContainer<OneStruct>>(m_Storage).Contains(id);
    }

private:
    std::tuple<MyContainer<LilStructs>...> m_Storage;
};

// 实现要求的MakeMegaContainer调用接口
template<typename... Structs>
auto MakeMegaContainer() {
    return StructStorage<Structs...>();
}

3. 修正测试代码

void Test() {
    struct SA { int x; };
    struct SB { float x; };
    struct SC { char x; };
    // 去掉错误的引用声明,用值类型接收返回对象
    auto tests = MakeMegaContainer<SA, SB, SC>();

    bool x = !tests.ContainsStruct<SA>(5);
}

追加问题解答

你提到的template<typename... LilStructs, uint64_t MAX_SIZE=4096>写法完全可行,C++允许可变参数模板放在模板参数列表前面,后面跟带默认值的固定模板参数,这种方式可以给所有容器统一设置最大容量,示例如下:

template<typename... LilStructs, uint64_t MAX_SIZE = 4096>
class StructStorage {
    // 其他逻辑不变
private:
    // 统一传递MAX_SIZE给所有MyContainer实例
    std::tuple<MyContainer<LilStructs, uint64_t, MAX_SIZE>...> m_Storage;
};

如果需要给不同结构体对应的容器设置不同容量,可以做一层类型包装,比如用std::pair<StructType, std::integral_constant<uint64_t, 自定义容量>>的形式传入模板参数,再做参数展开即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 17:39:05