Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the return type of std::ranges::max_element?

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.

like image 332
Be covered with white Avatar asked Nov 14 '25 22:11

Be covered with white


1 Answers

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
like image 118
康桓瑋 Avatar answered Nov 17 '25 21:11

康桓瑋



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!