I'm trying to iterate through a text file's lines using ranges:
auto iter_lines(std::ifstream& file)
{
auto lines = std::ranges::istream_view<char>(file) |
std::views::lazy_split('\n') |
std::views::transform([](auto&& line)
{
return std::string(line.begin(), line.end());
});
return lines;
}
I get a compilation error saying that std::string does not have such a constructor. I tried dropping transform and constructing the strings on the fly instead:
auto iter_lines(std::ifstream& file)
{
auto lines = std::ranges::istream_view<char>(file) |
std::views::lazy_split('\n');
return lines;
}
std::ifstream file("myfile.txt");
for (const auto& line : iter_lines(file))
std::cout << std::string(line.begin(), line.end()) << std::endl;
I got the same error. Which I found odd, since std::string can accept an iterator range in its constructor. So, I tried to iterate through the characters directly:
std::ifstream file("myfile.txt");
for (const auto& line : iter_lines(file))
{
for (char c : line)
std::cout << c;
std::cout << std::endl;
}
It did compile this way. My initial conclusion was that the type of line.begin() is not the same as the type of line.end() (IntelliSense seemed to agree) and since the constructor of std::string expects two iterators of the same type, it does not compile.
I tried to run the code above and against expectations it printed everything in one line! My final conclusion is that I have no idea how ranges work. I know that istream_view is single-pass, but since I'm using lazy_split I thought it shouldn't be a problem.
What exactly is going on here?
std::views::common, because thestd::stringconstructor is not able to construct from differing ierator/sentinel pairs. I would post this as a clear answer, but you are currently asking for a "thorough explination of" presumably everything you've said here.istream_view<char>already skips spaces and\n, so using\nto split the characters make no sense.