Search code examples
c++stringc++11findclang

Why can I not use find_if_not or find_if in C++?


According to this, find_if_not has been available since C++11, so I tried compiling with --std=c++11, and is defined in <algorithm> and is in the namespace std.

I have the following code:

#include <algorithm>
#include <iostream>
#include <string>
#include <cctype>
using namespace std;

int main(int argc, const char *argv[]) {
    string buffer;
    getline(cin, buffer);
    cout << buffer.substr(find_if(buffer.begin(), buffer.end(), isalnum) - buffer.begin()) << endl;
    return 0;
}

The idea is to simply echo the input but without any leading non-alphanumeric characters. However, I get a compiler error:

error: no matching function for
     call to 'find_if'
       cout << buffer.substr(find_if(buffer.begin(), buffer.end(), isal...
                             ^~~~~~~

I then tried to use find_if_not(buffer.begin(), buffer.end(), isspace) instead and I the same 'no matching function' error.

How can I use these functions find_if and find_if_not? I tried using all the required headers and C++ version.

When I run g++ --version I get:

Apple clang version 12.0.0 (clang-1200.0.32.29)
Target: x86_64-apple-darwin19.6.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin

And I am using macOS 10.15.7.


Solution

  • As suggested in a comment, you cannot use the <cctype> functions directly in the find_if and find_if_not functions. Those expect a callback that accept an unsigned char and return a bool, whereas the C functions isalpha and isspace and similar accept an int and return an int. Converting a function pointer to another type and then calling is not valid.

    The solution is to interface these functions through a lambda of the correct signature:

    cout << buffer.substr(buffer.begin() - find_if_not(buffer.begin(), buffer.end(),
        [](unsigned char c) -> bool {return isspace(c);})) << endl;
    

    Or to make a new function of the correct signature and pass that instead:

    bool is_space(unsigned char c) {
        return isspace(c);
    }
    

    At first I thought my problem was due to the functions find_if and find_if_not were not being defined somehow.

    For future reference, if I am getting:

    error: no matching function for call
    

    That means my arguments are incorrect.

    If I am getting:

    error: use of undeclared identifier
    

    That means I need to check the spelling, includes, C++ version, etc.