【问题标题】:Constructing a vector with istream_iterators使用 istream_iterators 构造向量
【发布时间】:2011-05-24 07:52:29
【问题描述】:

我记得曾经见过一种使用迭代器将整个二进制文件读入向量的巧妙方法。它看起来像这样:

#include <fstream>
#include <ios>
#include <iostream>
#include <vector>

using namespace std;

int main() {
    ifstream source("myfile.dat", ios::in | ios::binary);
    vector<char> data(istream_iterator(source), ???);
    // do stuff with data
    return 0;
}

这个想法是通过传递指定整个流的输入迭代器来使用vector 的迭代器范围构造函数。问题是我不确定要为 end 迭代器传递什么。

如何为文件末尾创建istream_iterator?我是不是完全记错了这个成语?

【问题讨论】:

    标签: c++ stl vector iterator


    【解决方案1】:

    在 C++11 中可以:

    std::ifstream source("myfile.dat", std::ios::binary);
    std::vector<char> data(std::istreambuf_iterator<char>(source), {});
    

    这种较短的形式避免了最棘手的解析问题,因为{} 参数消除了它作为参数或形式参数的歧义。

    @wilhelmtell 的答案也可以通过为data 采用大括号初始化程序来更新以避免此问题。仍然在我看来,使用{} 更简单,并且使初始化表单变得无关紧要。

    编辑

    或者,如果我们有 std::lvalue(也许是 std::xvalue 而不是 std::move):

    #include <vector>
    #include <fstream>
    
    template <typename T>
    constexpr T &lvalue(T &&r) noexcept { return r; }
    
    int main() {
        using namespace std;
    
        vector<char> data(
            istreambuf_iterator<char>(lvalue(ifstream("myfile.dat", ios::binary))),
            {}
        );
    }
    

    【讨论】:

    • 嗨@pepper_chico。我认为当您在数据构造函数的第二个参数中使用{} 时,编译器确定此参数的类型应为std::istreambuf_iterator&lt;char&gt; 并因此调用其默认构造函数std::istreambuf_iterator&lt;char&gt;{},我是否正确?这就是{} 的扩展内容吗?
    • @Stan 是的,它与std::istreambuf_iterator&lt;char&gt;() 的作用相同,这是一个有用的结构,与auto 一样工作,但用于值(默认值)而不是单独的类型。
    【解决方案2】:

    您需要 std::istreambuf_iterator&lt;&gt;,用于原始输入。 std::istream_iterator&lt;&gt; 用于格式化输入。至于文件的结尾,使用流迭代器的默认构造函数。

    std::ifstream source("myfile.dat", std::ios::binary);
    std::vector<char> data((std::istreambuf_iterator<char>(source)),
                           std::istreambuf_iterator<char>());
    

    编辑以满足C++'s most vexing parse。谢谢,@UncleBens。

    【讨论】:

    • 当心最麻烦的解析。
    • 有趣,这不会为我编译。我必须将std::istreambuf_iterator&lt;char&gt; 分配给一个变量或给它一个参数std::istreambuf_iterator&lt;char&gt;(0)。我想知道为什么。我正在使用 VS2005。
    • 谢谢,这正是我想要记住的模式。
    • 终于找到了答案。几乎是 SO 上唯一的一个。
    猜你喜欢
    • 1970-01-01
    • 2012-03-14
    • 2018-01-11
    • 1970-01-01
    • 1970-01-01
    • 2017-07-04
    • 2017-04-10
    • 2021-01-21
    • 2016-06-13
    相关资源
    最近更新 更多