ARTICLE AD BOX
We can use iota as a random_access_range:
static_assert(random_access_range<decltype(iota(0))>); // ok cout << (iota(0))[1]; // 1However, if we pass it via the range adapter common to get a common_range, the result is no longer a random_access_range:
static_assert(random_access_range<decltype(iota(0) | common)>); // failsThis becomes relevant in actual code, if we get an iota through a take and wish to calculate distance:
auto iota_2 = iota(0) | take(2); // cannot take distance, end is still a sentinel static_assert(!common_range<decltype(iota(0) | take(2))>); // auto diff_iota_2 = std::distance(iota_2.begin(), iota_2.end()); // compilation errorSo, we take the view through common adapter:
auto iota_2_common = iota(0) | take(2) | common; // now we can calculate distance if needed auto diff_iota_2 = distance(iota_2_common.begin(), iota_2_common.end());But, then we lost random access:
cout << iota_2_common[1]; // compilation error, iota_2_common is not random accessYes, we can use for the above iota(0, 2) which by itself is both random_access_range and common_range, thus supporting both required operations: distance and access by index. However, let's assume we started with an unbounded random access view, like iota, and we want to use take and common on it, then be able to still access it by index and calculate distance. Why is it not supported?
