为何C++20 filter视图赋值后未重新评估仍指向原元素?
C++20 Filter视图修改元素后begin()返回原元素的原因分析
首先明确标准规定的行为:
std::views::filter是惰性求值的视图,不存储元素,仅在需要时遍历底层容器筛选符合谓词的元素。- 每次调用
v1.begin(),视图都会从底层容器起始位置重新遍历,返回第一个满足i%2==0条件的元素迭代器。
按照标准,你提供的代码第二次调用v1.begin()应返回指向原容器中值为4的元素的迭代器,输出应为4而非13。若你实际得到13的输出,可能是以下原因:
编译器实现不符合标准
早期支持C++20的编译器(如GCC 10及更早版本)对范围视图的实现存在缺陷,filter_view::begin()可能未正确重新遍历底层容器筛选元素,而是错误复用了之前的迭代器位置。升级至GCC 11+、Clang 13+或MSVC 2022+等较新版本的编译器即可解决。错误复用了已存在的迭代器
若你的代码实际是保存迭代器后复用(而非每次调用v1.begin()),例如:auto it = v1.begin(); std::cout << *it << '\n'; // 输出2 *it = 13; std::cout << *it << '\n'; // 输出13此时迭代器
it仍指向底层容器中原先的元素(当前值为13)——filter视图的迭代器仅绑定底层容器的迭代器,不会因元素值变化导致不符合谓词而自动更新或跳转。只有重新调用v1.begin(),才会重新执行筛选逻辑找到新的符合条件的元素。对视图迭代器行为的误解
filter视图的迭代器不会跟踪元素是否仍满足谓词,仅在构造时定位到第一个符合条件的元素。修改元素值使其不再满足条件后,已存在的迭代器依然有效并指向该元素,但后续调用begin()会重新执行筛选流程,找到下一个符合条件的元素。
额外说明:filter视图允许通过迭代器修改底层容器的元素(只要底层容器可修改),但这种修改不会影响已创建的迭代器,仅会影响后续新迭代器的构造结果。
内容的提问来源于stack exchange,提问作者JohannesWilde
相关产品推荐
相关产品推荐

