I came across this weird behaviour where if you create a chunked view, by 2 elements, of a list and then try to print the front and the back while in a ranged for loop, the front method will work, but the back method won't. It will produce a compiler error saying that instantiating the .back() method requires a bidirectional iterator. Am I missing something?
Code to reproduce the error
#include <iostream>
#include <list>
#include <ranges>
#include <vector>
int main() {
std::list<int> nums_list = {0, 1, 2, 3, 4, 5};
auto rng = nums_list | std::views::chunk(2);
for (auto pair : rng) {
std::cout << pair.front(); // Front will work normally
std::cout << pair.back(); // No matching member function for 'back'.
}
}
I tried it with vector as well and it worked as expected.
It will produce a compiler error saying that instantiating the
.back()method requires a bidirectional iterator. Am I missing something?
The front() member is provided only if the view inherited from view_interface satisfies forward_range, and the back() member is provided if both common_range and bidirection_range are satisfied.
std::list satisfies common_range and bidirectional_range, so rng is also common_range and bidirectional_range†, which allows you to use back() on it, for example:
std::list<int> nums_list = {0, 1, 2, 3, 4, 5};
auto rng = nums_list | std::views::chunk(2);
auto back = rng.back();
However, the value type of rng, i.e. pair in your example, is specified as decltype(views::take(subrange(current_, end_), n_))†, where current_, end_ are the iterators of the std::list.
Since std::list::iterator cannot be subtracted, that is to say, they do not satisfy sized_sentinel_for, this makes the subrange they construct not sized_range, which ultimately results in take_view not being common_range, so its back() synthesis fails.
† To support back(), chunk_view also needs to know the size of the underlying range to find the starting position of the last chunk. This is not a problem for std::list as it is a sized_range.
†
views::take is used here to automatically handle the situation where the number of the last chunk is less than n.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With