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
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.
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))),
{}
);
}
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.