简体   繁体   English

C ++:ptr_fun()错误消息

[英]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. 它尝试查找(案例1)并删除(案例2)字符串中的第一个空格。 Here is the test results: 这是测试结果:

1) Line 1 causes "no matching function for call to find_if(...) " error. 1)第1行导致“没有匹配函数可调用find_if(...) ”错误。 This is because it tries to find std::isspace() , in stead of global isspace() . 这是因为它尝试查找std::isspace()而不是全局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. 2)如果将isspace()函数用ptr_fun()包装,如第3行和第4行,则第3行将导致“没有匹配函数调用ptr_fun(...) ”错误,并且第4行可以。

3) Line 5 causes "no matching function for call to not1(...) " error. 3)第5行导致“没有匹配函数调用not1(...) ”错误。 Line 6 generates lots of error message including something like "no match for call to (std::unary_negate<int(int)throw ()>) (char&) ". 第6行会生成许多错误消息,其中包括诸如“对(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() . 4)通过使用ptr_fun()包装,无论global还是std isspace() ,第7行和第8行都可以。

So: 所以:

1) Why do we need ptr_fun() in case 2 but not in case 1? 1)为什么在情况2中需要ptr_fun()而不在情况1中需要ptr_fun()

2) Why does std::isspace() work with ptr_fun() in case 2 but not in case 1? 2)为什么在情况2中std::isspace()ptr_fun()一起工作,而在情况1中为什么不行呢? How isspace() is resolved? isspace()如何解析?

3) What is the real purpose of ptr_fun() (and other similar STL functors) and how does it work? 3) ptr_fun() (和其他类似的STL函子)的真正目的是什么,它是如何工作的?

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 . 首先,在使用isspace之前,需要包括<cctype> 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. 但是,执行此操作后,第1行可能仍会出错,因为由于<locale>提供的isspace的重载而导致调用不明确,这可能已包含在您包含的其他标准库头文件之一中。 There's no need for ptr_fun to disambiguate, just use a static_cast 无需ptr_fun消除歧义,只需使用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. 至于关于not1的问题,这要求传递给它的谓词定义一个名为argument_type的类型,将其包裹在ptr_fun中即可。 The purpose of ptr_fun is to wrap a (non-member) function taking one or two arguments. ptr_fun的目的是包装带有一个或两个参数的(非成员)函数。 C++11 deprecates it in favor of std::function . C ++ 11弃用它,而推荐使用std::function

If your compiler supports lambda expressions, you can get rid of the not1 and ptr_fun calls. 如果您的编译器支持lambda表达式,则可以摆脱not1ptr_fun调用。

s.erase(s.begin(), find_if(s.begin(), s.end(), [](char c) {return !isspace(c)}));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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