#include <fstream>
#include <string>
#include <vector>
int main() {
auto fin = std::ifstream("tmp.txt");
auto pos = std::istream_iterator<std::string>(fin);
auto last = std::istream_iterator<std::string>{};
auto strs = std::vector<std::string>{};
for (; pos != last; ++pos) {
// Always COPY rather than MOVE the string here!
strs.emplace_back(std::move(*pos));
}
}
Note that strs.emplace_back(std::move(*pos)) will always COPY rather than MOVE the string, even if std::move(*pos).
This is due to std::istream_iterator<std::string>::operator* is defined as follows:
const T& operator*() const;
Which means we cannot move the cached objects even if the iterator is single-pass!
If the C++ standard had defined it as follows
T& operator*() const;
Then, we could
- use
std::istream_iterator<std::string>if we are sure to move each string exactly once, or,- use
std::istream_iterator<std::string const>if we would reference the same iterator more than once.
Why did the C++ standard not do so since C++11 has introduced move-semantics? What's the rationale behind the decision?
views::istreamsolves your issue.std::views::istreamis all I need! You can make your comment an answer.