Following is simple test program. It tries to find (case 1) and remove (case 2) the first space(s) in a string. Here is the test results:
1) Line 1 causes "no matching function for call to find_if(...)
" error. This is because it tries to find std::isspace()
, in stead of global isspace()
. So line 2 is ok.
2) If wrapping the isspace()
function with ptr_fun()
, like line 3 and line 4, and line 3 will cause "no matching function for call to ptr_fun(...)
" error, and line 4 is ok.
3) Line 5 causes "no matching function for call to not1(...)
" error. Line 6 generates lots of error message including something like "no match for call to (std::unary_negate<int(int)throw ()>) (char&)
".
4) By wrapping with ptr_fun(), line 7 and Line 8 are both ok, no matter if global or std isspace()
.
So:
1) Why do we need ptr_fun()
in case 2 but not in case 1?
2) Why does std::isspace()
work with ptr_fun()
in case 2 but not in case 1? How isspace()
is resolved?
3) What is the real purpose of ptr_fun()
(and other similar STL functors) and how does it work?
Thanks.
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
string s = " abc";
// case 1 (find the first space):
// find_if(s.begin(), s.end(), isspace); // line 1 (error)
// find_if(s.begin(), s.end(), ::isspace); // line 2 (ok)
// find_if(s.begin(), s.end(), ptr_fun(isspace)); // line 3 (error)
// find_if(s.begin(), s.end(), ptr_fun(::isspace)); // line 4 (ok)
// case 2 (trim leading spaces):
// s.erase(s.begin(), find_if(s.begin(), s.end(), not1((isspace)))); // line 5 (error)
// s.erase(s.begin(), find_if(s.begin(), s.end(), not1((::isspace)))); // line 6 (error)
// s.erase(s.begin(), find_if(s.begin(), s.end(), not1(ptr_fun<int, int>(::isspace)))); // line 7 (ok)
// s.erase(s.begin(), find_if(s.begin(), s.end(), not1(ptr_fun<int, int>(std::isspace)))); // line 8 (ok)
return 0;
}
First of all, you need to include <cctype>
before using isspace
. But line 1 might still error out after you do this because the call is ambiguous due to an overload of isspace
provided in <locale>
which is probably being included by one of the other standard library headers you've included. There's no need for ptr_fun
to disambiguate, just use a static_cast
find_if(s.begin(), s.end(), static_cast<int(*)(int)>(isspace));
As for the questions about not1
, that requires that the predicate passed to it define a type named argument_type
, which wrapping in ptr_fun
does for you. The purpose of ptr_fun
is to wrap a (non-member) function taking one or two arguments. C++11 deprecates it in favor of std::function
.
If your compiler supports lambda expressions, you can get rid of the not1
and ptr_fun
calls.
s.erase(s.begin(), find_if(s.begin(), s.end(), [](char c) {return !isspace(c)}));
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.