问题
For example, if I want to find the smallest element of a collection, but only the smallest even element, I'd like to call ranges::min_element
with a filtered range like so:
using ranges::views::filter;
using ranges::min_element;
std::vector<int> vals{1,2,3,4,5};
auto minVal = min_element(vals | filter([](int next){return next % 2 == 0;}));
How do I check if the returned range is empty, and if not, access the value?
The same applies to other range algorithms like ranges::find
, ranges::find_if
, etc.
回答1:
Unfortunately you cannot pass a temporary range into ranges algorithms.
This is because they will return a ranges iterator (possibly ranges::end(rng)
) upon completion. If you pass a temporary, the returned iterator would be invalid; referencing a temporary. The ranges library detects this and returns a dummy sentinel, ranges::dangling instead of an iterator.
The proper way to do this is to first compose your filtered range then call the algorithm.
std::vector<int> vals {1, 2, 3, 4, 5};
auto even_vals = vals | filter([](int val){return val % 2 == 0;});
auto minVal = min_element(even_vals);
if (minVal == even_vals.end())
std::cout << "no values\n";
else
std::cout << *minVal; // prints "2"
Demo
来源:https://stackoverflow.com/questions/58400325/how-do-i-check-if-ranges-algorithms-like-find-if-returned-a-value