使用模板元编程在 C++ 中生成组合列表的最简单方法是什么?

What's the easiest way to generate a list of combinations in C++ using template meta-programming?

提问人:ajl123 提问时间:7/18/2023 最后编辑:ajl123 更新时间:7/18/2023 访问量:108

问:

我找到了SO帖子:在C++中生成组合列表的最简单方法是什么?,它告诉我们如何在运行时生成大小为真/假元组的所有可能组合的列表。N

但是,如果我们知道,我在编译时也有同样的问题。我们将如何使用模板递归进行模板元编程?假设在编译时已知,并且唯一的值是 或 。NNtruefalse

重述主要问题:“通常,您会遇到一个问题,其中属性 A 可以是真或假,属性 B 也可以是真或假,依此类推。我们想测试A为真而B为假的每个组合,依此类推。

// Say N is 3, then the following tuple of booleans would be generated
[true,true,true]
[true,true,false]
[true,false,true]
[true,false,false]
[false,true,true]
[false,true,false]
[false,false,true]
[false,false,false]

可能的函数签名可能如下所示:

template <std::size_t N>
constexpr auto boolean_combinations()

如果可能,我想使用 C++ 17 或更高版本来执行此操作。

C++ 递归 模板-元编程

评论

0赞 davidhigh 7/18/2023
你试过了什么?在链接的帖子中,您可以找到几种替代方案。你能把其中一个翻译成TMP吗?
0赞 HarryP2023 7/18/2023
我想知道递归是否能够解决这个问题。N = 0 和 N = 1 的基本情况,然后从那里开始
0赞 Marek R 7/18/2023
您希望如何处理所有这些组合?
0赞 康桓瑋 7/18/2023
这可以通过 轻松实现。views::cartesian_product
0赞 Jerry Coffin 7/18/2023
可以这么说,这几乎是拖累。唯一的区别是将这些 s 作为单个整数中的位生成,而不是作为单独的实体。std::integer_sequenceinteger_sequencebool

答:

4赞 Nelfeal 7/18/2023 #1

在 C++ 17 中,您不需要模板元编程。一个函数可以做到这一点:constexpr

#include <array>

auto constexpr pow2(std::size_t exponent) -> std::size_t {
    return exponent == 0 ? 1 : 2 * pow2(exponent - 1);
}

template<std::size_t N>
constexpr auto boolean_combinations() {
    static_assert(N < sizeof(std::size_t));
    std::array<std::array<bool, N>, pow2(N)> list{}; // initialization needed in C++17
    for (auto i = 0; i < list.size(); ++i) {
        for (auto j = 0; j < N; ++j) {
            list[i][j] = static_cast<bool>(i & (1 << j));
        }
    }
    return list;
}

演示

评论

0赞 ajl123 7/18/2023
哦,生病了!但是,是否可以使用 C++17 做到这一点?
0赞 Nelfeal 7/18/2023
@ajl123 查看编辑。在 C++14 中,它会有点复杂。