简化编译时二叉树类型的创建

Simplify creation of compile-time binary tree type

提问人:Astor 提问时间:9/17/2023 更新时间:9/17/2023 访问量:79

问:

在为较大的 C++ 项目创建二叉树类型的上下文中,我需要创建一个表示每个级别中的节点的编译时类型。

有谁知道,使用最新的标准,如果有一种更简单、更漂亮的方法来在下面(非常简化的)代码中为任意值创建 ?LevelTypenLevels

我只需要类型,所以我可以为类定义它。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++ 模板 组元编程 参数包

评论

0赞 user17732522 9/17/2023
什么C++版本?对于最近的 C++ 版本,您不再需要元编程。使用 C++20 或更高版本时,任何普通的树实现都应该在编译时工作,可能对分配方案进行一些必要的调整。如果还需要将树传递给运行时,则还需要确保分配器从固定数组进行分配,需要首先确定其大小。constexpr
0赞 Astor 9/17/2023
谢谢。这就是我问题的关键。对于我需要的类,该类必须在编译时基于 创建。只是为了创建类型,在 c++23 中是否有更简单的方法?TreeLevelTypenLevels
1赞 user17732522 9/17/2023
你到底需要什么?应该如何使用?为什么树结构需要在类型中编码?Tree
0赞 JaMiT 9/17/2023
从代码中推导出功能需求是一件痛苦的事情(而且不可靠——不同的人看到不同的东西)。最好把它们写出来。
0赞 user17732522 9/17/2023
确切的要求很重要,因为否则它很简单:在 C++20 及更高版本的编译时工作得很好,但可能无法满足您想象的所有用例。struct Tree { std::vector<Tree> children; };

答:

2赞 user17732522 9/17/2023 #1

您不需要,因为返回非引用。std::remove_referencemake_tuple

你不需要 .您可以直接指定。std::make_tuplestd::tuple

你不需要成为一个函数。如果您只想要该类型,它可以是别名模板。make_tree

有了上面的内容,你也不需要被定义,因为它只是为了获得返回类型而调用的,而作为非引用类型,它同样不需要:make_tree_implremove_reference

template <auto... Is>
auto make_tree_impl(std::index_sequence<Is...>)
    -> Tree<std::tuple<std::array<double, std::size_t{1} << Is>...>>;

template <std::size_t nLevels>
using make_tree = decltype(make_tree_impl(std::make_index_sequence<nLevels>{}));

然后,您可以直接使用以下命令获取类型:

using T = make_tree<nLevels>;

该函数也可以在 C++20 及更高版本中替换为等效的 lambda,但这不会使其看起来更具可读性。make_tree_impl