C++中如何简化任意层数的编译期二叉树LevelType创建?
问题描述
在大型C项目的二叉树类型构建场景中,我需要创建一个表示各层节点的编译期类型。请问利用最新C标准,是否存在更简洁优雅的方式,为下述简化代码中任意nLevels值创建LevelType?我仅需该类型用于定义Tree类。
原代码:
#include<array> #include<iostream> template <typename LevelType> class Tree { public: LevelType level ; }; template <std::size_t nLevels, std::size_t... Is> constexpr auto make_tree_impl(std::index_sequence<Is...>) { return Tree <typename std::remove_reference <decltype(std::make_tuple(std::array<double,1<<Is>()...))>::type>(); }; template <std::size_t nLevels> constexpr auto make_tree() { return make_tree_impl<nLevels>(std::make_index_sequence<nLevels>()); }; int main() { const unsigned int nLevels = 5; auto tree = make_tree<nLevels>(); std::cout << std::is_same<decltype(tree), Tree<std::tuple<std::array<double,1>, std::array<double,2>, std::array<double,4>, std::array<double,8>, std::array<double,16>>>>::value << std::endl ; return 0; }
优化方案(基于C++20+)
当然可以,利用C++20的模板元编程特性,我们可以直接通过模板别名推导目标类型,去掉冗余的辅助函数,让代码更简洁直观:
1. 核心:直接生成层级类型的模板别名
我们可以跳过函数推导,直接用std::index_sequence展开生成对应的tuple类型:
#include <array> #include <tuple> #include <utility> template <typename LevelType> class Tree { public: LevelType level; }; // 定义生成层级tuple的模板别名 template <std::size_t... Is> constexpr auto tree_levels_helper(std::index_sequence<Is...>) -> std::tuple<std::array<double, 1 << Is>...>; template <std::size_t nLevels> using TreeLevels = decltype(tree_levels_helper(std::make_index_sequence<nLevels>())); // 直接定义对应层级数量的Tree类型别名 template <std::size_t nLevels> using TreeOfLevels = Tree<TreeLevels<nLevels>>;
2. 简化的使用方式
现在你可以直接用模板别名创建Tree实例,不需要调用任何辅助函数:
#include <iostream> #include <type_traits> int main() { constexpr std::size_t nLevels = 5; TreeOfLevels<nLevels> tree; // 验证类型是否匹配预期 std::cout << std::is_same_v<decltype(tree), Tree<std::tuple<std::array<double,1>, std::array<double,2>, std::array<double,4>, std::array<double,8>, std::array<double,16>>>> << std::endl; return 0; }
3. 更进一步:把层级逻辑内聚到Tree类中
如果希望Tree类直接关联层级数量,可以把类型定义直接写在类内部:
#include <array> #include <tuple> #include <utility> template <std::size_t nLevels> class Tree { // 内部生成层级类型 template <std::size_t... Is> constexpr auto levels_helper(std::index_sequence<Is...>) -> std::tuple<std::array<double, 1 << Is>...>; public: using LevelType = decltype(levels_helper(std::make_index_sequence<nLevels>())); LevelType level; constexpr Tree() = default; }; // 使用示例 #include <iostream> #include <type_traits> int main() { Tree<5> tree; std::cout << std::is_same_v<decltype(tree.level), std::tuple<std::array<double,1>, std::array<double,2>, std::array<double,4>, std::array<double,8>, std::array<double,16>>>> << std::endl; return 0; }
优化优势
- 去掉了冗余的
make_tree_impl和make_tree函数,代码更精简; - 类型定义直观,层级关系在模板别名中一目了然,便于维护;
- 完全保留编译期计算特性,无任何运行时开销;
- 逻辑内聚性更强,适合大型项目的类型管理。
内容的提问来源于stack exchange,提问作者Astor
相关产品推荐
相关产品推荐

