c ++:ptr_fun()错误消息

时间:2014-01-17 16:39:07

标签: c++

以下是简单的测试程序。它试图找到(案例1)并删除(案例2)字符串中的第一个空格。以下是测试结果:

1)第1行导致“没有匹配函数来调用find_if(...)”错误。这是因为它试图找到std::isspace(),而不是全局isspace()。所以第2行还可以。

2)如果用isspace()包裹ptr_fun()函数,如第3行和第4行,第3行将导致“没有匹配函数来调用ptr_fun(...)”错误,并且行4还可以。

3)第5行导致“没有匹配函数来调用not1(...)”错误。第6行会生成大量错误消息,包括“不匹配来调用(std::unary_negate<int(int)throw ()>) (char&)”。

4)通过ptr_fun()包装,第7行和第8行都可以,无论是全局还是标准isspace()

所以:

1)为什么我们在案例2中需要ptr_fun()但在案例1中不需要?{/ p>

2)为什么std::isspace()在案例2中与ptr_fun()一起使用,而在案例1中则不然?如何解决isspace()

3)ptr_fun()(以及其他类似的STL仿函数)的真正目的是什么?它是如何工作的?

感谢。

#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;
}

1 个答案:

答案 0 :(得分:1)

首先,您需要在使用isspace之前添加<cctype>。但是,在执行此操作后,第1行可能仍然会出错,因为<locale>中提供的isspace过载导致调用不明确,这可能包含在您包含的其他标准库标题之一中。 ptr_fun无需消除歧义,只需使用static_cast

即可
find_if(s.begin(), s.end(), static_cast<int(*)(int)>(isspace));

关于not1的问题,要求传递给它的谓词定义一个名为argument_type的类型,它包含在ptr_fun中。 ptr_fun的目的是用一个或两个参数包装一个(非成员)函数。 C ++ 11弃用它而使用std::function

如果你的编译器支持lambda表达式,你可以摆脱not1ptr_fun调用。

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