如何将整个流读入std :: vector?

Rob*_*son 5 c++ stl vector stream ifstream

在这里阅读了一个答案,展示了如何使用以下一(2)个内容将整个流读入std :: string:

std::istreambuf_iterator<char> eos;    
std::string s(std::istreambuf_iterator<char>(stream), eos);
Run Code Online (Sandbox Code Playgroud)

对于做类似的读取一个二进制流成的东西std::vector,为什么我不能简单地替换charuint8_tstd::stringstd::vector

auto stream = std::ifstream(path, std::ios::in | std::ios::binary);    
auto eos = std::istreambuf_iterator<uint8_t>();
auto buffer = std::vector<uint8_t>(std::istreambuf_iterator<uint8_t>(stream), eos);
Run Code Online (Sandbox Code Playgroud)

以上产生编译器错误(VC2013):

1> d:\non-svn\c ++\library\i\file\filereader.cpp(62):错误C2440:'':无法从'std :: basic_ifstream>'转换为'std :: istreambuf_iterator>'1>
with 1> [1> _Elem = uint8_t 1>] 1>
没有构造函数可以采用源类型,或者构造函数重载解析是模糊的

Bar*_*rry 11

只有一种类型不匹配.ifstream只是一个typedef:

typedef basic_ifstream<char> ifstream;
Run Code Online (Sandbox Code Playgroud)

因此,如果您想使用不同的底层类型,您只需要告诉它:

std::basic_ifstream<uint8_t> stream(path, std::ios::in | std::ios::binary);    
auto eos = std::istreambuf_iterator<uint8_t>();
auto buffer = std::vector<uint8_t>(std::istreambuf_iterator<uint8_t>(stream), eos);
Run Code Online (Sandbox Code Playgroud)

这对我行得通.

或者,由于Dietmar说这可能有点粗略,你可以这样做:

auto stream = std::ifstream(...);
std::vector<uint8_t> data;

std::for_each(std::istreambuf_iterator<char>(stream),
              std::istreambuf_iterator<char>(),
              [&data](const char c){
                  data.push_back(c);
              });
Run Code Online (Sandbox Code Playgroud)


Mik*_*our 5

ifstream是一个流char,而不是uint8_t.您将需要basic_ifstream<uint8_t>istreambuf_iterator<char>为类型相匹配.

如果没有一些工作,前者可能无法工作,因为图书馆只需要支持charwchar_t; 所以你可能想要istreambuf_iterator<char>.