std :: transform和move语义 [英] std::transform and move semantics

查看:164
本文介绍了std :: transform和move语义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用Boost.Filesystem在目录中创建文件列表。我使用 boost :: filesystem :: recursive_directory_iterator std :: copy 将每个路径放入std :: vector作为 boost :: filesystem :: directory_entry 对象。我希望作为std :: strings输出到文件,所以我做了以下(\\\
,以避免使用<<):

I'm using Boost.Filesystem to create a listing of files in a directory. I use boost::filesystem::recursive_directory_iterator and std::copy to put each path into a std::vector as a boost::filesystem::directory_entry object. I wish to output to the file as std::strings though, so I did the following (\n to avoid the use of <<):

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 实现移动语义?

However the problem with this is it creates two vectors, the original of which is immediately cleared because it is not needed. This sounds like a perfect place for move semantics, but n3242 only provides the same two overloads of transform as in C++98. Is it possible to implement move semantics with std::transform? If it is not, would writing a custom loop be better?

我在Windows XP上使用GCC 4.5.2(MinGW)。

I'm using GCC 4.5.2 (MinGW) on Windows XP.

推荐答案

这看起来像是 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是否有效。

A move iterator is simply an iterator which moves its dereference result. Note that the class needs to support move semantics for this to even make a difference; I don't know if Boost FS does.

注意,如果你的目标是在不同的行输出它们,重做错了。格式化打印不应要求输入数据采用某种格式,这会违背目的。为数据添加换行符只是为了使其具有换行符是令人讨厌的。它由 ostream_iterator 为您处理:

Note if your goal is to output them on separate lines, you're doing it wrong. Formatted printing shouldn't require the input data be in a certain format, that defeats the purpose. Adding newlines to your data just to format it to have newlines is nasty. It's handled for you by ostream_iterator anyway:

std::copy(buffer.begin(), buffer.end(), //               vvvv
            std::ostream_iterator<std::string>(out_file, "\n"));

任何更复杂的,请不要事先修改您的数据。

Anything more complex, make a lambda in for printing; don't modify your data beforehand.

这篇关于std :: transform和move语义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆