@rubenvb's answer is great.
As an alternative
bool get_line_into_vector( std::istream& is, std::vector<std::string>& v ) {
std::string tmp;
if (!std::getline(is, tmp))
return false;
v.push_back(std::move(tmp));
return true;
}
std::vector<std::string> lines;
while(get_line_into_vector( ifs, lines ))
{} // do nothing
This is rubenvb's solution with the temporary moved into a helper function.
We can avoid the small buffer optimization sized copies of characters with this:
bool get_line_into_vector( std::istream& is, std::vector<std::string>& v ) {
v.emplace_back();
if (std::getline(is, v.back()))
return true;
v.pop_back();
return false;
}
this can (in an edge case) cause an extra massive reallocation, but that is asymptotically rare.
Unlike @pschill's answer, here the invalid states are isolated to within a helper function, and all the flow control is centered around avoiding those invalid states from leaking.
The nice thing is that
std::vector<std::string> lines;
while(get_line_into_vector( ifs, lines ))
{} // do nothing
is how you use it; which of these two implementations you use is isolated to within the get_line_into_vector
function. That lets you swap between them and determine which is better.