3
何らかの理由で、下記のコードでclang ++とg ++が100%CPUを使用し、システムがハングするまでメモリをいっぱいにします。範囲の再帰関数(範囲-v3から)は、コンパイルを分岐させます。なぜですか?
に注意してください。これは話のおもちゃの例です。私は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
関数は、整数および単項関数の範囲をとる範囲に機能素子ごとに適用され、マッピングされた要素の和を生成する再帰を実装することを意味します。
2つの質問があります:(1)発散する動作の原因は何ですか、(2)コンパイルがクラッシュしないようにテールビューを作成して渡す必要がありますか?
を出力しますか? – Jarod42
@ Jarod42ああ、私はコンパイラをクラッシュさせてしまったので、条件付きリターンを書くのを忘れてしまった。私はそれを修正します。私のガッフェをすぐに指摘してくれてありがとう。 – Timtro
2番目のブランチは、関数 'rec_map_sum'を無限にインスタンス化します。 – Jarod42