I wrote the following expression:
//definition and initialization
std::map<int ,double> my_map;
my_map[1]=2.0;
my_map[2]=3.0;
And then I wanted to find the max_element through the function std::ranges::max_element with range adaptors(for study)
auto result{std::ranges::max_element(my_map|take(2))};
After getting the result, I tried to use "->" to get the first value of the pair of value contain in the iterator result
result->first;//I think (*result) will get a pair.In this example, it will be {2,3.0}
However the compiler pointed out the error that No viable overloaded 'operator->'
And I found that the type of result is *counted_iterator<...> *
But when I tested
std::vector<int> my_vector{1,2,3};
auto max_number{std::ranges::max_element(my_vector|take(3))};
I could use *max_number to get the max integer 3 in the vector.
And I found that the type of max_number is *__normal_iterator<...> *
I am confusing with the iterator type returned by std::ranges::max_element which determine when I can use the operator -> .
I sincerely appreciate your support.
The iterator type of take_view will vary depending on how refined the underlying range is.
When the underlying range is std::map, take_view's begin() will return a counted_iterator that records the correct size because we can calculate it through std::min(my_map.size(), n). Since counted_iterator only provides operator->() if the underlying iterator is a contiguous_iterator, which map::iterator clearly is not, you cannot apply operator->() to it.
When the underlying range is std::vector that satisfies sized_range and random_access_range, take_view's begin() and end() will optimally return my_vector.begin() and my_vector.begin() + size() to reduce template instantiation, which is the iterator of the original vector, which is__normal_iterator in libstdc++.
ranges::max_element returns the iterator of the origin range pointing to the max element, so in your example, it will return counted_iterator and vector::iterator respectively, which is the result you observed.
If you want to get the max element directly instead of an iterator, you can use ranges::max:
std::vector<int> my_vector{1,2,3};
auto max = std::ranges::max(my_vector | std::views::take(2));
std::cout << max << "\n"; // 2
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