如何利用整数序列简化Store类中重复的成员与函数定义?
解决Store类中重复成员与模板特化的问题
你的Store类通过手动声明m_0到m_7成员,以及对应的get模板特化,产生了大量重复代码。利用C++的**整数序列(std::integer_sequence)**可以彻底消除这类重复,以下是具体实现方案:
原始问题代码
class Store { template <int N> using map = std::unordered_map<typename Topo<N>::type*, std::unique_ptr<Node<N>>>; template <int N> map<N>& get(); map<0> m_0; template <> map<0>& get<0>() { return m_0; } map<1> m_1; template <> map<1>& get<1>() { return m_1; } // ... map<7> m_7; template <> map<7>& get<7>() { return m_7; } };
优化方案:用整数序列自动生成成员与通用get函数
核心思路是用std::tuple存储所有map<N>实例,借助std::integer_sequence自动展开0到7的整数序列,避免手动逐个声明成员和特化函数。
基础实现版本
#include <tuple> #include <utility> // 用于std::make_index_sequence class Store { template <int N> using map = std::unordered_map<typename Topo<N>::type*, std::unique_ptr<Node<N>>>; // 用tuple存储所有map实例,std::make_index_sequence<8>自动生成0-7的序列 std::tuple<map<0>, map<1>, map<2>, map<3>, map<4>, map<5>, map<6>, map<7>> m_maps; public: // 通用get模板,无需特化,直接通过std::get获取对应位置的map template <int N> map<N>& get() { return std::get<N>(m_maps); } };
高扩展性版本(适配任意整数范围)
如果后续需要调整N的范围(比如扩展到0-15),可以用基类模板结合整数序列进一步提升灵活性:
#include <tuple> #include <utility> // 基类:根据传入的整数序列生成对应的map成员 template <std::size_t... Ns> struct StoreBase { template <std::size_t N> using map = std::unordered_map<typename Topo<N>::type*, std::unique_ptr<Node<N>>>; std::tuple<map<Ns>...> m_maps; }; // Store继承基类,指定整数范围为0-7(std::make_index_sequence<8>生成0到7的序列) class Store : public StoreBase<std::make_index_sequence<8>> { public: // 复用基类的map类型定义 template <int N> using map = StoreBase<std::make_index_sequence<8>>::template map<N>; // 通用get函数 template <int N> map<N>& get() { return std::get<N>(this->m_maps); } };
方案说明
- 消除重复代码:无需手动编写每个
m_N成员和get的模板特化,整数序列会自动展开所有需要的map<N>实例。 - 扩展性强:如果需要调整N的范围,仅需修改
std::make_index_sequence<8>中的数字,无需改动其他代码。 - 类型安全:
std::get<N>会在编译期检查N是否在有效范围内,避免运行时错误。
内容的提问来源于stack exchange,提问作者Marco Amagliani
相关产品推荐
相关产品推荐

