简体   繁体   中英

c++: ptr_fun() error messages

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM