|
template <input_range _Rp, class _Proj = identity, indirect_unary_predicate<projected<iterator_t<_Rp>, _Proj>> _Pred> |
|
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Rp> |
|
operator()(_Rp&& __r, _Pred __pred, _Proj __proj = {}) const { |
|
auto __pred2 = [&](auto&& __e) { return !std::invoke(__pred, std::forward<decltype(__e)>(__e)); }; |
|
return ranges::__find_if_impl(ranges::begin(__r), ranges::end(__r), __pred2, __proj); |
|
} |
The lambda here should specify the return type as bool, such as [&](auto&& __e) -> bool because the type that satisfies boolean-testable does not necessarily have to be bool:
#include <algorithm>
const struct Boolean {
Boolean() = default;
Boolean(Boolean&&) = delete;
operator bool() const;
const Boolean& operator!() const;
} boolean;
#ifdef __clang__
static_assert(std::__boolean_testable<Boolean>);
#endif
int main() {
// libc++ rejects
auto it = std::ranges::find_if_not(" ", [&](char) -> auto& { return boolean; });
}
https://godbolt.org/z/4M15cvarx
llvm-project/libcxx/include/__algorithm/ranges_find_if_not.h
Lines 46 to 51 in 8dd3bc1
The lambda here should specify the return type as
bool, such as[&](auto&& __e) -> boolbecause the type that satisfiesboolean-testabledoes not necessarily have to bebool:https://godbolt.org/z/4M15cvarx