范围的递归函数(从范围 v3 开始)导致编译发散:为什么
Recursive function of range (from range-v3) causes compilation to diverge: why?
出于
某种原因,下面列表中的代码导致 clang++ 和 g++ 使用 100% CPU,并填满内存,直到我的系统挂起。
请注意,这是一个演讲的玩具示例。我知道accumulate
和transform
是执行此操作的标准方法,但此代码是推理链中的中间点。
#include <iostream>
#include <range/v3/all.hpp>
using namespace ranges;
template <typename F, typename R, typename T>
T rec_map_sum(F f, R r, T tally) {
if (ranges::begin(r) == ranges::end(r))
return tally;
else {
auto r_head = *ranges::begin(r);
auto r_tail = r | view::drop(1);
return rec_map_sum(f, r_tail, tally + f(r_head));
// this also crashes:
// return rec_map_sum(f, r[{1, end}], tally + f(r_head));
}
}
int main() {
std::cout << rec_map_sum([](int x) { return x * x; }, view::iota(0, 10), 0)
<< std::endl;
return 0;
}
rec_map_sum
函数旨在实现一个递归,该递归采用整数范围和一元函数,将函数逐个元素应用于范围,并生成映射元素的总和。
有两个问题:(1(发散行为的原因是什么,(2(我应该如何制作和传递尾视图,以使编译不会崩溃?
Jarod42指出了这个问题,但解决方案非常简单。您需要一个可以采用任何范围的文字擦除视图。幸运的是,这样的事情存在。将代码更改为:
template <typename F, typename R, typename T>
T rec_map_sum(F f, R r, T tally) {
auto r2 = any_view<T>{r};
if (ranges::begin(r2) == ranges::end(r2))
return tally;
else {
auto r_head = *ranges::begin(r2);
auto r_tail = r2 | view::drop(1);
return rec_map_sum(f, r_tail, tally + f(r_head));
}
}
这打印了 285。
相关文章:
- C ++枚举范围无法使用-std=c ++ 98进行编译,但使用-std=c ++ 11可以
- 编译期间矢量下标超出范围
- 递归应用 C++20 范围适配器会导致编译时无限循环
- C++ 在编译过程中 strtok 函数 Eclipse 说没有在范围内声明?
- 在编译时何时计算范围::视图?
- 实现编译检查以避免C++嵌套范围
- 解析模板和范围后获取编译文件?
- 我已经编写了C++代码将 boost::optional 视为一个范围,但它无法编译
- C++ if 语句范围内的宏未编译
- 在 mingw64- 变量下的窗口中编译 openvpn3 时出错,未在范围内声明
- 范围的递归函数(从范围 v3 开始)导致编译发散:为什么
- 非命名空间范围内的显式专用化不会在 GCC 中编译
- 编译错误 在 C++ 上,Calcarea 未在此范围内声明
- 试图过渡到GTK3(针对GTK -3.0库编译)时,在此范围内未声明GTK_Object
- 代码块编译错误.Cin 未在此范围内声明
- 编译 gsoap-onvif 求解 #error:M_ASN1_STRING_data“未在此范围内声明
- 无法编译 - 范围问题
- GCC 的<实验/范围>过滤器视图不能使用无限范围 iota() 进行编译
- 在Mac上编译时,NULLPTR未在范围中声明
- 表示范围所需的位的编译时计算