C++/BOOST filesystem fs::directory_iterator一个滑稽的错误

错误来源于,用

fs::directory_iterator iter(folderPath), end;

然后for循环

for (; iter != iter_end; ++iter) {}

最开始没问题,后来说加个进度条,统计一下所有文件数量,用了std::distance,

int totalFiles = std::distance(iter, iter_end);std::cout << " totalFiles is " << totalFiles << std::endl;
for (; iter != iter_end; ++iter) {}

奇怪的事情发生了

明明统计得到几百个文件,可是for循环一次都不动。

写了个测试代码:

#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
#include <boost/filesystem.hpp>namespace fs = boost::filesystem;
int main() {std::vector<int> numbers = {1, 2, 3, 4, 5};// 创建迭代器auto beginIter = numbers.begin();auto endIter = numbers.end();// 计算距离std::cout <<"iter == iter_end? " << (beginIter == endIter) <<std::endl;std::ptrdiff_t dist = std::distance(beginIter, endIter);std::cout <<"iter == iter_end? " << (beginIter == endIter) <<std::endl;std::cout << "距离: " << dist << std::endl;std::cout << "*beginIter : " << *beginIter << std::endl;fs::directory_iterator iter("/home/hqw"), end;std::cout <<"iter == iter_end? " << (iter == end) <<std::endl;std::ptrdiff_t dist2 = std::distance(iter, end);std::cout <<"iter == iter_end? " << (iter == end) <<std::endl;std::cout << "距离: " << dist2 << std::endl;return 0;
}
iter == iter_end? 0
iter == iter_end? 0
距离: 5
*beginIter : 1
距离: 5
iter == iter_end? 0
iter == iter_end? 1
距离: 101

通过输出结果可知,默认情况std::distance()不会去操作迭代器beginIter的,beginIter在原位,但是遇到boost的filesystem::directory_iterator迭代器(不确定是否全boost如此),他把我迭代器给“用掉”了,想想也可以理解,迭代器不是平铺的数据,想得到俩迭代器的“距离”,势必做了个iter++操作

  template<typename _InputIterator>inline _GLIBCXX14_CONSTEXPRtypename iterator_traits<_InputIterator>::difference_type__distance(_InputIterator __first, _InputIterator __last,input_iterator_tag){// concept requirements__glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)typename iterator_traits<_InputIterator>::difference_type __n = 0;while (__first != __last){++__first;++__n;}return __n;}

但是理论上你可以留个备份,然后给我恢复,不动我的输入才对。

这可能就和boost本身对迭代器的封装有关了。

也就是他distance的原理是让我的iter去++,最后去接近end,并且没给我备份恢复?

因为std::distance是模板操作,而迭代器是boost定义的,算是boost自己的问题,他不给副本,而走了智能指针,导致std::distance直接把iter给改掉了。

朴素的++iter操作,改变了boost的迭代器指向

结论就是避坑,单独给一个临时iter,或者别用stl接口去搞boost了。

或者问题根源在于:不要混用stl和boost

#include <boost/range.hpp>// ...std::vector<int> numbers{1, 2, 3, 4, 5};
auto range = boost::make_iterator_range(numbers);std::ptrdiff_t distance = boost::distance(range);

收回我刚才的话,不混用也没用,谨慎使用boost的迭代器,boost自己的distance函数一样改变了iter2的指向

如果有C++17,直接用C++的filesystem替代。

#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
#include <boost/filesystem.hpp>
#include <boost/range.hpp>
#include <boost/range/iterator_range.hpp>
// #include <filesystem>
#include <experimental/filesystem>
// namespace fs = boost::filesystem;
// namespace fs = std::filesystem;
int main() {    std::experimental::filesystem::directory_iterator iter3("/home/hqw"), end3;std::cout <<"iter == iter_end? " << (iter3 == end3) <<std::endl;std::ptrdiff_t dist3 = std::distance(iter3, end3);std::cout <<"iter == iter_end? " << (iter3 == end3) <<std::endl;std::cout << "距离: " << dist3 << std::endl;return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/4636.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

XYCTF2024 部分w

RE 1. 聪明的信使 基础爆破 #include<stdio.h> #include<string.h> int main() {char enc[] "oujp{H0d_TwXf_Lahyc0_14_e3ah_Rvy0acwc!}";char flag[41] {0};int i, j;for (i 0; i < strlen(enc); i){for (j 33; j < 127; j){if ((j < 9…

Skill Check: Fundamentals of Large Language Models

Skill Check: Fundamentals of Large Language Models 完结&#xff01;

Vue项目中引入高德地图步骤详解,附示例代码

vue中如何使用高德地图&#xff0c;下面为您详解。 步骤一&#xff1a;安装高德地图的JavaScript API 在Vue项目的根目录下打开终端&#xff0c;执行以下命令安装高德地图的JavaScript API&#xff1a; npm install amap/amap-jsapi-loader --save 步骤二&#xff1a;创建地…

什么?你还不懂文件系统和软硬链接?

文章目录 序言认识磁盘磁盘在系统中的管理熟悉磁盘各个分区 软硬链接软链接硬链接 序言 首先熟悉一下一些专有名词(了解即可,但必须有一个概念认识) 固态:SSD,笔记本中常装的,台式机中也可以装,常见的对应接口M.2和SATA接口 磁盘:90年代常用的数据存储设备,或是现在企业级数据…

IPv4 NAT(含Cisco配置)

IPv4 NAT&#xff08;含Cisco配置&#xff09; IPv4私有空间地址 类RFC 1918 内部地址范围前缀A10.0.0.0 - 10.255.255.25510.0.0.0/8B172.16.0.0 - 172.31.255.255172.16.0.0/12C192.168.0.0 - 192.168.255.255192.168.0.0/16 这些私有地址可在企业或站点内使用&#xff0c…

从零开始的软件测试学习之旅(四)web项目工作流程介绍

WEB手工项目 项目介绍项目技术分析项目学习准备工作如何快速熟悉项目举例熟悉TPshop项目 总体系统项目介绍项目与数据库测试流程什么是软件需求需求评审 测试计划测试方案测试计划和测试方案的区别 项目介绍 满足经典三层架构:前端 后端 数据库 前端:运行在用户端的浏览器和客…

同仁堂医养拟赴港上市,养老产业的盈利难题有了答案?

提及银发经济&#xff0c;大众可能最先想到的就是养老产业&#xff0c;在市场需求推动下&#xff0c;这一细分赛道的增长已势不可挡。单从入局者的积极性就可以把握到赛道前景之广阔。 天眼查专业版数据显示&#xff0c;截至目前&#xff0c;我国拥有养老相关企业36.2万家&…

线上办理离婚快速离婚,无需双方见面异地可办

现在离婚有两种方式 一种是协议离婚&#xff0c;双方都同意的情况下&#xff0c;可以去民政局协议离婚&#xff0c;有30天冷静期&#xff0c;冷静期过后需要双方再次去民政局办理离婚手续。 另一种是诉讼离婚&#xff0c;一方不同意离婚&#xff0c;可以选择诉讼离婚。可以全…

【PPT设计】颜色对比、渐变填充、简化框线、放大镜效果、渐变形状配图、线条的使用

目录 图表颜色对比、渐变填充、简化框线放大镜效果渐变形状配图 线条的使用区分标题与说明信息区分标题与正文,区分不同含义的内容**聚焦****引导****注解****装饰** 图表 颜色对比、渐变填充、简化框线 小米汽车正式亮相&#xff01;你们都在讨论价格&#xff0c;我全程只关…

jackson.dataformat.xml 反序列化 对象中包含泛型

重点&#xff1a; JacksonXmlProperty localName 指定本地名称 JacksonXmlRootElement localName 指定root的根路径的名称&#xff0c;默认值为类名 JsonIgnoreProperties(ignoreUnknown true) 这个注解写在类上&#xff0c;用来忽略在xml中有的属性但是在类中没有的情况 Jack…

python_django农产品物流信息服务系统6m344

Python 中存在众多的 Web 开发框架&#xff1a;Flask、Django、Tornado、Webpy、Web2py、Bottle、Pyramid、Zope2 等。近几年较为流行的&#xff0c;大概也就是 Flask 和 Django 了 Flask 是一个轻量级的 Web 框架&#xff0c;使用 Python 语言编写&#xff0c;较其他同类型框…

Eclipse C++ 无法debug 问题

环境&#xff1a; ubuntu20.04 Eclipse CDT&#xff08;x86_64) 工程&#xff0c;使用的是默认的CMake Project 现象&#xff1a; 1. 使用Eclipse&#xff0c; 加了断点后&#xff0c;debug 无法停在断点&#xff1b;step over 执行后是从main 直接执行到exit &#xff…

poi-tl自定义渲染策略学习

文章目录 实现逻辑参考代码注意点 实现逻辑 自定义渲染策略实现逻辑&#xff1a; 找到模板中的表格标签render方法接收java中对应模板表格标签的所有list数据执行自定义渲染逻辑 参考代码 word模板如下&#xff1a; 实体类&#xff1a; Data public class GksxRowData {/…

Linux多进程(二)进程通信方式三 共享内存

共享内存提供了一个在多个进程间共享数据的方式&#xff0c;它们可以直接访问同一块内存区域&#xff0c;因此比使用管道或消息队列等通信机制更高效。在多进程程序中&#xff0c;共享内存通常与信号量一起使用&#xff0c;以确保对共享内存的访问是线程安全的。 一、打开/创建…

07_for循环返回值while循环

文章目录 1.循环返回值2.yield接收for返回值3.scala调用yield方法创建线程对象4.scala中的while循环5.scala中的流程控制 1.循环返回值 for循环返回值是Unit 原因是防止产生歧义&#xff1b; 2.yield接收for返回值 // 2.yield关键字打破循环&#xff0c;可以使for循环输出…

webpack面试题(持续汇总ing。。。)

webpack的编译过程 初始化 此阶段&#xff0c;webpack会将CLI参数、配置文件、默认配置进行融合&#xff0c;形成一个最终的配置对象。对配置的处理过程是依托一个第三方库 yargs 完成的。此阶段相对比较简单&#xff0c;主要是为接下来的编译阶段做必要的准备目前&#xff0c;…

LLaMA 3:大模型之战的新序幕

作者 | 符尧 OneFlow编译 翻译&#xff5c;杨婷、宛子琳、张雪聃 本文要点概览&#xff1a; 文本数据的扩展可能已经达到了极限&#xff0c;因为易于获取的网络文本资源&#xff08;如Common Crawl、GitHub、ArXiv等&#xff09;已基本被充分利用。 尽管如此&#xff0c;通过更…

数据结构 - C/C++ - 数组

目录 结构特性 内存布局 结构样式 结构拓展 数据初始 元素访问 插入元素 删除元素 查找元素 修改元素 结构设计 成员变量 构造函数 功能函数 示例代码 结构特性 长度固定&#xff1a;数组的长度在创建时已经被确定&#xff0c;如果需要动态改变数组的长度&#…

C++面向对象程序设计 - 多继承,以及基类与派生类转换

单继承是一个类是从另一个基类派生类而来的&#xff0c;多继承则是一个派生类是同两个或多个基类&#xff0c;派生类从两人或多个基类中继承所需的属性。 声明多重继承的方法&#xff1a; class D: public A, private B, protected C { 类D新增加的成员 } 一、多重继承派生类的…

Vue---组件

Vue—组件 目录 Vue---组件定义组件全局组件局部组件 组件通讯***重点***父子通信之父传子&#xff08;props&#xff09;父子通信之子传父&#xff08;$emit&#xff09;ref属性&#xff08;$refs&#xff09; 动态组件插槽命名插槽 定义组件 全局组件 vue2中template只能传…