何时使用 ostream_iterator

When to use ostream_iterator

据我所知,我们可以在c++11中使用ostream_iterator来打印容器。
例如,

std::vector<int> myvector;
for (int i=1; i<10; ++i) myvector.push_back(i*10);

std::copy ( myvector.begin(), myvector.end(), std::ostream_iterator<int>{std::cout, " "} );

我不知道什么时候以及为什么我们使用上面的代码,而不是传统的方式,例如:

for(const auto & i : myvector) std::cout<<i<<" ";

在我看来,传统的方式更快,因为没有copy,对吗?

std::ostream_iterator 是一个单通道输出迭代器,所以它可以用在任何接受这种迭代器的算法中。用它来输出int-s的vector只是为了展示它的能力

In my opinion, the traditional way is faster because there is no copy, am I right?

您可能会在这里找到:http://en.cppreference.com/w/cpp/algorithm/copy that copy is implemented quite similarly to your for-auto loop. It is also specialized for various types to work as efficient as possible. On the other hand writing to std::ostream_iterator is done by assignment to it, and you can read here : http://en.cppreference.com/w/cpp/iterator/ostream_iterator/operator%3D 它解析为 *out_stream << value; 操作(如果分隔符被忽略)。

您可能还会发现此迭代器存在在末尾插入额外尾随定界符的问题。为了解决这个问题(可能在 C++17 中)会有一个新的单通道 OutputIterator std::experimental::ostream_joiner

一个简短的(可能是愚蠢的)示例,其中使用迭代器很有用。关键是您可以将数据定向到任何接收器 - 文件、控制台输出、内存缓冲区。无论你选择什么输出,MyData::serialize都不需要改变,你只需要提供OutputIterator。

struct MyData {
    std::vector<int> data = {1,2,3,4};

    template<typename T>
    void serialize(T iterator) {
        std::copy(data.begin(), data.end(), iterator);
    }
};

int main()
{
    MyData data;

    // Output to stream 
    data.serialize(std::ostream_iterator<int>(std::cout, ","));

    // Output to memory
    std::vector<int> copy;
    data.serialize(std::back_inserter(copy));

    // Other uses with different iterator adaptors:
    // std::front_insert_iterator
    // other, maybe custom ones
}

区别在于多态与硬编码流。
std::ostream_iterator 从继承自 std::ostream 的任何 class 构建自身,因此在运行时,您可以更改或 连接 迭代器以写入差异输出流基于函数运行上下文的类型。

第二个代码段使用硬编码 std::cout,无法在运行时更改。