我正在使用Boost.Filesystem来创建目录中的文件列表。我使用boost::filesystem::recursive_directory_iterator
和std::copy
将每个路径作为boost::filesystem::directory_entry
对象放入std :: vector中。我希望以std :: strings的形式输出到文件,所以我做了以下(\ n以避免使用<<):
std::vector<boost::filesystem::directory_entry> buffer; //filled with paths
...
std::vector<std::string> buffer_native(buffer.size());
//transform directory_entry into std::string, and add a \n, so output is formatted without use of <<
std::transform(buffer.begin(),buffer.end(),buffer_native.begin(), [](boost::filesystem::directory_entry de)->std::string
{
std::string temp=de.path().string();
temp+="\n";
return temp;
}
buffer.clear();
std::copy(buffer_native.begin(),buffer_native.end(),std::ostream_iterator<std::string>(out_file));
然而,问题是它创建了两个向量,其原始值立即被清除,因为它不需要。这听起来像移动语义的完美位置,但是n3242只提供与C ++ 98相同的两个转换重载。是否可以使用std::transform
实现移动语义?如果不是,那么编写自定义循环会更好吗?
我在Windows XP上使用GCC 4.5.2(MinGW)。
答案 0 :(得分:9)
这似乎是make_move_iterator
的作业:
std::transform(make_move_iterator(buffer.begin()),
make_move_iterator(buffer.end()), buffer_native.begin(),
[](boost::filesystem::directory_entry&& de) -> std::string
{
// still makes copy :/ perhaps native() would work better, I don't know
std::string temp = de.path().string();
temp += "\n";
return temp;
}
移动迭代器只是一个移动其取消引用结果的迭代器。请注意,类需要支持移动语义才能产生差异;我不知道Boost FS是否会这样做。
请注意,如果您的目标是在不同的行上输出它们,那么您做错了。格式化打印不应要求输入数据采用某种格式,这样会破坏目的。为数据添加新行只是为了将其格式化为新行是令人讨厌的。无论如何,它都由ostream_iterator
处理:
std::copy(buffer.begin(), buffer.end(), // vvvv
std::ostream_iterator<std::string>(out_file, "\n"));
任何更复杂的东西,制作一个用于打印的lambda;不要事先修改数据。