【发布时间】:2012-03-30 14:57:32
【问题描述】:
我写了一个非常简单的文件管理数据库,基本上是这样的:
class FileDB
{
public:
FileDB(std::string dir) : rootDir(dir) { }
void loadFile(std::string filename, File &file) const;
void saveFile(std::string filename, const File &file) const;
private:
std::string rootDir;
}
现在我想遍历数据库中包含的所有文件,例如使用std::iterator:
void iterateFiles()
{
FileDB filedb("C:\\MyFiles");
for (FileDB::iterator file_it = filedb.begin(); file_it != filedb.end(); ++file_it)
{
File f = *file_it;
// do something with file
}
}
我已经阅读了类似问题的答案,有些建议派生std::iterator,有些建议使用std::iterator_traits,但我真的不明白该怎么做。尝试实现自定义迭代器时可能会出现什么问题?什么是简单而优雅的方法呢?
编辑: 请不要考虑使用 boost,我的问题更具概念性。
编辑 2:
FileDB 的工作方式如下:
-
根目录
- foo1
- bar1
- foo1bar1_1.txt
- foo1bar1_2.txt
- bar2
- foo1bar2_1.txt
- foo1bar2_2.txt
- bar1
foo2
-
fooN
-
barM
- fooNBarM_x.txt
-
- foo1
所以基本上,我可以通过文件名找到文件。
由于我的容器不在内存中,因此我没有指向其数据的指针。所以我的想法是将文件的路径存储在迭代器中。这样,我可以通过字符串比较来实现operator==,因为路径应该是唯一的。从fileDB.end() 返回的迭代器将是一个空字符串,而operator* 将使用其文件路径调用fileDB::loadFile()。
我最担心的是operator++。有了文件名,我就可以找到包含目录并搜索下一个文件,但这确实无效。关于如何做到这一点的任何想法?还是我的整个概念完全错了?
【问题讨论】:
-
最简单的方法大概是使用
iterator_facadefrom Boost.Iterator. -
更简单的方法是使用 boost::filesystem 并避免编写任何代码...
-
好的,我应该知道我应该添加信息,我不想使用 boost ;) 主要是因为我想了解迭代器是如何工作的。
-
Iterator 在概念上很简单,但充满了烦人的实现细节 Boost.Iterator 照顾。不要重新发明轮子。