Constructing a vector with istream_iterators

后端 未结 2 500
梦谈多话
梦谈多话 2020-12-08 16:38

I recall once seeing a clever way of using iterators to read an entire binary file into a vector. It looked something like this:

#include 
#i         


        
相关标签:
2条回答
  • 2020-12-08 17:16

    In C++11 one could:

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

    This shorter form avoids the most vexing parse problem because of the {} argument, which removes ambiguity of it being an argument or a formal parameter.

    @wilhelmtell's answer could also be updated to avoid this problem by adopting a brace initializer for data. Still in my view, using {} is more simple and turn the initialization form irrelevant.

    EDIT

    Or, if we had std::lvalue (and maybe std::xvalue instead of 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))),
            {}
        );
    }
    
    0 讨论(0)
  • 2020-12-08 17:18

    You want the std::istreambuf_iterator<>, for raw input. The std::istream_iterator<> is for formatted input. As for the end of the file, use the stream iterator's default constructor.

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

    Edited to satisfy C++'s most vexing parse. Thanks, @UncleBens.

    0 讨论(0)
提交回复
热议问题