英文:
What's the easiest way to generate a list of combinations in C++ using template meta-programming?
问题
我找到了这个Stack Overflow帖子:https://stackoverflow.com/questions/9593787/whats-the-easiest-way-to-generate-a-list-of-combinations-in-c,它告诉我们如何在运行时生成一个大小为N
的true/false元组的所有可能组合的列表。
但是,如果我们知道N
,我有相同的问题在编译时该如何做呢?我们如何使用模板元编程和模板递归来实现这一点?假设N
在编译时已知,且唯一的值是true
或false
。
为了重新表述主要问题:“通常,你会遇到这样一个问题,属性A可以是true或false,属性B也可以是true或false,依此类推。我们想要测试A为true而B为false的每种组合,以此类推。”
// 假设N为3,那么将生成以下布尔元组
[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或更高版本来实现这个功能。
英文:
I found the SO post: https://stackoverflow.com/questions/9593787/whats-the-easiest-way-to-generate-a-list-of-combinations-in-c, which tells us how to generate at runtime a list of all possible combinations of a true/false tuple of size N
.
However, I have the same question at compile-time if we know N
. How would we do this with template meta-programming using template recursion? Assume that N
is known at compile time and the only values are true
, or false
.
To restate the main question: "Oftentimes, you have a problem where property A can be either true or false, property B also either true or false, and so on. We want to test every combination of A being true while B being false, and so on."
// 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]
A possible function signature might look like:
template <std::size_t N>
constexpr auto boolean_combinations()
If possible, I would like to do this using C++17, or later.
答案1
得分: 4
在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{}; // 在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;
}
英文:
In C++17, you don't need template metaprogramming for that. A constexpr
function can do the trick:
#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;
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论