以下是简单的测试程序。它试图找到(案例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;
}
答案 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表达式,你可以摆脱not1
和ptr_fun
调用。
s.erase(s.begin(), find_if(s.begin(), s.end(), [](char c) {return !isspace(c)}));