4

Consider the following code:

#include <cctype>
#include <ranges>

constexpr inline auto filter_upper = std::views::filter(::isupper);

The new range adaptors filter_upper works fine with global old c-function ::isupper, but if I replace with std::isupper, I got this compiler error:

<source>:4:69: error: no match for call to '(const std::ranges::views::__adaptor::_RangeAdaptor<std::ranges::views::<lambda(_Range&&, _Pred&&)> >) (<unresolved overloaded function type>)'
    4 | constexpr inline auto filter_upper = std::views::filter(std::isupper);
      |                                                                     ^
In file included from <source>:1:
/opt/compiler-explorer/gcc-10.2.0/include/c++/10.2.0/ranges:1102:4: note: candidate: 'constexpr auto std::ranges::views::__adaptor::_RangeAdaptor<_Callable>::operator()(_Args&& ...) const [with _Args = {}; _Callable = std::ranges::views::<lambda(_Range&&, _Pred&&)>]'
 1102 |    operator()(_Args&&... __args) const
      |    ^~~~~~~~

Where is the problem?

康桓瑋
  • 33,481
  • 5
  • 40
  • 90

1 Answers1

3

There appear to be several overloads of isupper in the std namespace and the compiler doesn't know which one to pick. If you use static_cast<int (*)(int)>(std::isupper) it compiles.

Anyway, I believe that you are not allowed to use the address of a std function, so better use a lambda:

constexpr inline auto filter_upper = std::views::filter([](unsigned char c) { return std::isupper(c); });
metalfox
  • 6,301
  • 1
  • 21
  • 43