Why can't I use operator * ? errors generated by gcc 14.
#include <algorithm>
#include <ranges>
using namespace std;
int main() {
auto rng = views::iota(0, 3);
const auto [a, b] = * ranges::min_element(views::cartesian_product(rng, rng));
return 0;
}
prog.cc: In function 'int main()':
prog.cc:7:29: error: no match for 'operator*' (operand type is 'std::ranges::borrowed_iterator_t<std::ranges::cartesian_product_view<std::ranges::iota_view<int, int>, std::ranges::iota_view<int, int> > >')
7 | const auto [a, b] = * ranges::min_element(views::cartesian_product(rng, rng));
|
std::ranges::min_element"borrows" an iterator from the given range. In case of an rvaluestd::cartesian_product(and any similar view), this would dangle in most circumstances since the lifetime of thestd::cartesian_productwould end after the iterator would be returned, sostd::ranges::danglingis returned. See this related question: Why do std range algorithms return std::ranges::dangling for rvalue arguments instead of... well, just working?This would be safe in this case since the elements would be copied from before the
cartesian_productrvalue's lifetime ends, but it prevents accidentally writing something like this:The fix is to make it an lvalue: