何时使用ostream_iterator

时间:2016-06-07 19:52:50

标签: c++11 iterator ostream

据我所知,我们可以在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,我是对的吗?

2 个答案:

答案 0 :(得分:2)

std::ostream_iterator是单通道OutputIterator,因此可以在任何接受此类迭代器的算法中使用。使用它来输出int-s的向量只是为了展示它的能力。

  

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

您可以在此处找到:http://en.cppreference.com/w/cpp/algorithm/copy该副本的实现方式与您的for-auto循环非常相似。它还专门用于各种类型,以尽可能高效地工作。另一方面,写入std :: ostream_iterator是通过赋值来完成的,你可以在这里阅读: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
}

答案 1 :(得分:0)

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

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