如何在range::concat缓冲区指定范围正确使用range::minmax_element?
修复range::minmax_element在concat_view上的段错误与编译问题
问题根源
- 迭代器越界:当前
buf的元素总数不足,计算后的终止迭代器超出buf有效范围,访问越界触发段错误。 - 变量遮蔽:内部作用域的结构化绑定变量与外部同名变量重名,导致外部变量始终保持初始值,后续逻辑无效。
- v2定义错误:代码中
std::vector<test> v2 = {{}};会创建含默认构造对象的容器,而非预期的空容器。
修复方案
- 修正v2为真正的空容器。
- 添加范围合法性检查,避免迭代器越界。
- 避免变量遮蔽,将内部作用域的结果赋值给外部变量。
- 补充v1元素数量(模拟业务后续补充的场景),确保迭代器范围有效。
修复后完整代码
#include <algorithm> #include <chrono> #include <iostream> #include <range/v3/all.hpp> #include <ranges> #include <vector> struct test { double price; std::chrono::system_clock::time_point timestamp; }; int main() { using namespace std::chrono; using namespace std::chrono_literals; std::vector<test> v1 = {{1.0, std::chrono::sys_days{1970y / 1 / 1}}, {2.0, std::chrono::sys_days{1970y / 1 / 2}}, {3.0, std::chrono::sys_days{1970y / 1 / 3}}, {4.0, std::chrono::sys_days{1970y / 1 / 4}}, {5.0, std::chrono::sys_days{1970y / 1 / 5}}, {6.0, std::chrono::sys_days{1970y / 1 / 6}}}; // 补充足够元素 std::vector<test> v2; // 修正为空容器 const auto buf = ranges::concat_view(v1, v2); const auto lower_tf = 1; const auto upper_tf = 5; const auto cnum_at_i = 0; auto lower_tf_limit = ranges::rbegin(buf); auto upper_tf_limit = ranges::rbegin(buf); { const auto start_idx = cnum_at_i + 1; const auto end_idx = start_idx + (upper_tf / lower_tf); // 检查范围合法性,防止越界 if (end_idx <= static_cast<size_t>(ranges::distance(ranges::rbegin(buf), ranges::rend(buf)))) { auto [min_it, max_it] = ranges::minmax_element( ranges::rbegin(buf) + start_idx, ranges::rbegin(buf) + end_idx, {}, &test::price); // 将结果赋值给外部变量 lower_tf_limit = min_it; upper_tf_limit = max_it; } } if (lower_tf_limit != ranges::rbegin(buf) && upper_tf_limit != ranges::rbegin(buf)) std::cout << "lower_tf_limit->price = " << lower_tf_limit->price << std::endl; }
关键说明
- 内部作用域使用
min_it/max_it替代同名变量,避免遮蔽外部变量,同时保留了原有的作用域结构。 - 新增的范围检查从根本上避免了越界访问,解决段错误问题。
- 修正v2的定义,符合业务中空容器的预期。
内容的提问来源于stack exchange,提问作者Andrew
相关产品推荐
相关产品推荐

