Home > front end >  Why std::isupper can not apply to std::any_of directly but isupper(from C header) can
Why std::isupper can not apply to std::any_of directly but isupper(from C header) can

Time:01-19

see code below:

#include <algorithm>
#include <ctype.h>
#include <cctype>
#include <string>

int main() {
    std::string str = "a String";
    
    // compile fail: template deduction fail for _Pred
    // return std::any_of(str.begin(), str.end(), std::isupper);

    // OK:
    return std::any_of(str.begin(), str.end(), isupper); // or ::isupper
}

both std::isupper and isupper have same declaration according to cppreference.com:

Defined in header < cctype>

int isupper( int ch );

Defined in header <ctype.h>

int isupper( int ch );

So, why?

CodePudding user response:

There's more than one isupper function is namespace std. One is int std::isupper(int) defined in <cctype>, and the other is template <typename charT> bool isupper( charT ch, const locale& loc ) defined in <locale>.

It seems that your <cctype> also includes <locale>, and make the compiler cannot deduce which isupper is used. You can try the following:

return std::any_of(str.begin(), str.end(), static_cast<int (*)(int)>(std::isupper));

However, as others mentioned, you'd better use a lambda to wrap the call to std::isupper:

return std::any_of(str.begin(), str.end(), [](unsigned char c) { return std::isupper(c); });
  •  Tags:  
  • c
  • Related