如何处理C++模板可变参数并将其包装为自定义容器实例
问题根源
编译报错由三处核心问题导致:
std::get类型参数使用错误
你的m_Storagetuple存储的元素类型是MyContainer<StructA>、MyContainer<StructB>这类容器实例,不是StructA、StructB本身。你直接用std::get<OneStruct>(m_Storage)查找元素时,tuple中不存在OneStruct类型的元素,编译器匹配失败才会抛出类型不匹配的报错。- 测试代码语法错误
auto& tests = StructStorage <SA, SB, SC>();尝试用非const左值引用绑定临时对象,C++标准不支持这种操作,会触发编译错误。 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
相关产品推荐
相关产品推荐

