问题描述
我正在尝试根据发送给函数的类型创建一个位集.但是让我们稍微减少一下测试用例.
I'm trying to create a bitset according to the type send to the function. But let's reduce the test case a little.
警告:在此示例中,我使用的是自动gcc扩展程序,不需要使用模板参数.
Warning : I'm using auto gcc extension for this example, I don't need to use template parameter.
namespace hana = boost::hana;
constexpr decltype(auto) rec(auto i, auto max, auto f, auto returnValue) {
return returnValue |= f(i);
if constexpr (i < max) //"infinite" loop if no constexpr
return rec(i + hana::size_c<1>, max, f, returnValue);
else
return returnValue;
}
constexpr decltype(auto) foo(auto ct, auto ... type) {
constexpr auto tuple = hana::make_tuple(type...);
constexpr unsigned long returnValue = 0L;
constexpr auto f = [tuple, ct] (auto i) {
if (hana::contains(tuple, ct[i]))
return 0 << decltype(i)::value;
else
return 0;
};
return rec(hana::size_c<0>, hana::size_c<3>, f, returnValue);
}
struct T1 {};
struct T2 {};
struct T3 {};
int main () {
constexpr auto t1 = hana::type_c<T1>;
constexpr auto t2 = hana::type_c<T2>;
constexpr auto t3 = hana::type_c<T3>;
constexpr auto ct = hana::make_tuple(t1, t2, t3);
constexpr auto test = foo(ct, t1, t2);
}
好像我的元组不被认为是可搜索的,但是如果我尝试相同的hana ::包含在lambda之外,我就没问题.
Seems like my tuple is not considered Searchable, but if I try the same hana::contains outside the lambda I got no problem.
整个错误很大,因此请在此处进行检查:实时演示
The whole error is huge so check it there : live demo
顺便说一句,我尝试使用for循环执行此操作,但失败了.您知道在C ++ 17/20中做这种事情的好方法吗?
By the way, I tried to do this with a for loop but failed. Do you know a good way of doing this kind of things in C++17/20 ?
推荐答案
该错误是由于使用手动递归导致的越界访问引起的.函数式编程的部分目的是提供一种构造,以消除此类错误的可能性.
The error is caused by an out of bounds access caused by the use of manual recursion. Part of the purpose of functional programming is to provide constructs to eliminate the possibility of these kinds of mistakes.
这里有一些示例,但是建议您阅读有关该概念的手册 hana::Foldable
,因为它实际上是使用Boost.Hana的基础.
Here are a few examples, but it is recommended to take a look at the manual for the concept hana::Foldable
as it is really foundational in using Boost.Hana.
hana::fold_left
为您隐藏递归并可以减少递归通过快速跟踪进行的递归调用量:
hana::fold_left
hides the recursion for you and can reduce the amount of recursive calls via fast-tracking:
constexpr decltype(auto) foo = [](auto ct, auto ... type) {
constexpr auto tuple = hana::make_tuple(type...);
return hana::fold_left(hana::make_range(hana::size_c<0>, hana::size_c<3>), 0L,
[tuple, ct](auto returnValue, auto i)
{
// returnValue param is not constexpr
if (hana::contains(tuple, ct[i])) {
return returnValue | (1 << decltype(i)::value);
}
else
{
return returnValue;
}
}
);
};
hana::unpack
使用可变包扩展完全消除了递归:
hana::unpack
eliminates recursion altogether using variadic pack expansion:
constexpr decltype(auto) foo = [](auto ct, auto ... type) {
constexpr auto tuple = hana::make_tuple(type...);
auto f = [tuple, ct](auto i)
{
return hana::contains(tuple, ct[i]) ? (1 << decltype(i)::value) : 0;
};
return hana::unpack(hana::make_range(hana::size_c<0>, hana::size_c<3>),
[f](auto ...i) { return (f(i) | ...); }
);
};
这篇关于如何使用Boost Hana删除元编程递归的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!