C++標準ライブラリ提供レンジアダプタstd::views::filter
適用後の要素に対する変更操作には十分留意すること。
変更操作により要素がフィルタ条件を満たさなくなる場合、C++ライブラリ仕様上は未定義動作(undefined behavior)を引き起こす。この問題は遅延評価によりフィルタ条件が複数評価されるケースで初めて表面化するため、ライブラリ仕様違反が潜在化するリスクが高い。C++ Ranges難しい(´・ω・)(・ω・`)ネー
#include <iostream> #include <ranges> #include <vector> bool is_odd(int x) { return x % 2 != 0; } std::vector vec1 = { 1, 2, 3, 4, 5, 6 }; std::vector vec2 = vec1, vec3 = vec1; for (int& e: vec1 | std::views::filter(is_odd) | std::views::reverse) { e += 10; // OK: 条件is_odd(e)は維持される std::cout << e << ' '; } // 15 13 11 を出力 for (int& e: vec2 | std::views::filter(is_odd) | std::views::reverse) { e += 1; // NG: 条件is_odd(e)を満たさないためUB std::cout << e << ' '; } // GCC/Clang: SEGV発生 // 上記例から reverse, filter 適用順を入れ替え for (int& e: vec3 | std::views::reverse | std::views::filter(is_odd)) { e += 1; // NG: 本来はUBだが... std::cout << e << ' '; } // GCC/Clang: 6 4 2 を出力
C++20 24.7.4.3/p1より引用。
Modification of the element a
filter_view::iterator
denotes is permitted, but results in undefined behavior if the resulting value does not satisfy the filter predicate.
関連URL