2

I can't tell if I'm just missing something obvious here but I cannot seem to get find_if to work.

#include <iostream>
#include <string>
#include <algorithm>

using namespace std;

bool isspace(char c)
{
    return c == ' ';
}

int main()
{
    string text = "This is the text";

    string::iterator it = find_if(text.begin(), text.end(), isspace);

    cout << *it << endl;

    return 0;
}

I've looked at the example here, http://www.cplusplus.com/reference/algorithm/find_if/, which compiles and runs but I cannot see the difference between that and my program other than the vector -> string thing but I don't see why that would make a difference.

I know cctype has the better functions for isspace but I wanted to make sure that wasn't messing me up.

My error:

test.cpp: In function ‘int main()’:
test.cpp:16:68: error: no matching function for call to ‘find_if(std::basic_string<char>::iterator, std::basic_string<char>::iterator, <unresolved overloaded function type>)’
     string::iterator it = find_if(text.begin(), text.end(), isspace);
                                                                    ^
test.cpp:16:68: note: candidate is:
In file included from /usr/include/c++/4.8/algorithm:62:0,
                 from test.cpp:3:
/usr/include/c++/4.8/bits/stl_algo.h:4456:5: note: template<class _IIter, class _Predicate> _IIter std::find_if(_IIter, _IIter, _Predicate)
     find_if(_InputIterator __first, _InputIterator __last,
     ^
/usr/include/c++/4.8/bits/stl_algo.h:4456:5: note:   template argument deduction/substitution failed:
test.cpp:16:68: note:   couldn't deduce template parameter ‘_Predicate’
     string::iterator it = find_if(text.begin(), text.end(), isspace);
                                                                    ^
  • 1
    Try `find_if(text.begin(), text.end(), ::isspace)` (note extra `::` before `isspace`) – Oktalist Jan 15 '15 at 19:20
  • 1
    @Oktalist: qualifying it with `::` is not enough. The OP needs to cast it to a `(bool (*)(char))` so the compiler can resolve which `isspace` to use. It's possible for the C++ headers to include ``, in which case there are 2 `isspace` functions in the global namespace. – Cornstalks Jan 15 '15 at 19:26
  • @Cornstalks Nah he needs to not `using namespace std;` :P – Borgleader Jan 15 '15 at 19:28
  • 3
    [There are also multiple reasons why you should (generally) avoid naming your function with the same name as functions provided by the C and C++ standard libraries](http://stackoverflow.com/questions/11892976/why-is-my-log-in-the-std-namespace) (this being one of those reasons). – Cornstalks Jan 15 '15 at 19:31

1 Answers1

7

The key part of the error is:

test.cpp:16:68: error: no matching function for call to ‘find_if(
    std::basic_string<char>::iterator, 
    std::basic_string<char>::iterator, 
    <unresolved overloaded function type>)’ // <==

Unresolved overloaded function type!? That's because you defined:

bool isspace(char );

But there is already one named isspace:

bool isspace(int );

and another named std::isspace that you bring in with using:

template <class charT>
bool isspace(charT, const locale&);

And the template can't know which one it is you want. So you can either specify it explicitly:

string::iterator it = find_if(
    text.begin(), 
    text.end(), 
    static_cast<bool(*)(char)>(isspace)); // make sure yours gets called

Or, simpler, just change your name.

Or, simplest, just delete yours and stop using namespace std;. That way, isspace unambiguously references exactly the one function you wanted to use in the first place.

Barry
  • 286,269
  • 29
  • 621
  • 977