In C++, if a function returns a std::pair<int, int>
, we can auto-receive it as follows:
auto pr = some_function();
std::cout << pr.first << ' ' << pr.second;
Now, C++17 standard provides a beautiful way of unpacking this pair directly into separate variables as follows:
auto [x, y] = some_function();
std::cout << x << ' ' << y;
And then there is std::minmax_element()
library function, which returns a pair of iterators. So if I pass a vector<int>
to this function, it gives me back pair of iterators pointing to the smallest and the largest element in the vector.
Now one way I can accept these iterators is as usual, and then de-reference them later as follows.
std::vector<int> v = {4,1,3,2,5};
auto [x, y] = std::minmax_element(v.begin(), v.end());
std::cout << (*x) << ' ' << (*y); // notice the asterisk(*)
Now my question is: Is there any way to de-reference them while unpacking? Or more precisely, given the following code, can I replace var1
and var2
with something that is valid C++ and prints the value pointed by those iterators?
std::vector<int> v = {4,1,3,2,5};
auto [var1, var2] = std::minmax_element(v.begin(), v.end());
std::cout << var1 << ' ' << var2; // notice there is NO asterisk(*)
Sure. Write a function that takes a pair of dereferencable things and returns the result of dereferencing them:
template <typename Iterator,
typename R = typename std::iterator_traits<Iterator>::reference>
auto deref(std::pair<Iterator, Iterator> p)
-> std::pair<R, R>
{
return {*p.first, *p.second};
}
And then use that function:
auto [var1, var2] = deref(std::minmax_element(v.begin(), v.end()));
Noting that this is UB if the range is empty because you're dereferencing the end iterator, twice.
Or, to be nicer:
struct deref_t {
template <typename It,
typename R = typename std::iterator_traits<Iterator>::reference>
friend auto operator|(std::pair<It, It> p, deref_t)
-> std::pair<R, R>
{
return { *p.first, *p.second };
}
};
inline constexpr deref_t deref{};
Which allows:
auto [var1, var2] = std::minmax_element(v.begin(), v.end()) | deref;
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