目前,如果要取消谓词,则必须使用std::<algorithm>_if_not
变体或lambda。但是为了学术,我想知道这是否可能:
std::string s("hello");
std::find_if(s.begin(), s.end(), std::not1(::ispunct));
如果不编写自己的函数对象,如何使这段代码工作?
答案 0 :(得分:9)
请记住,将char
传递给来自C标准库的字符分类函数(以及toupper
和tolower
)的正确方法是首先将其转换为{ {1}}然后转到unsigned char
。
使用int
和std::ref
这是轻量级的,也是错误的。使用reference_wrapper
或std::function<bool(int)>
更重要,也是错误的。在所有这些情况下,字符串中的std::function<bool(char)>
会直接转换为char
,这不是正确的方法。
如果你坚持不使用lambda,那么
int
是一种正确的方法。否则
std::find_if(s.begin(), s.end(), std::not1(std::function<bool(unsigned char)>(::ispunct)));
更容易理解 - 更短。
答案 1 :(得分:4)
一元谓词类型必须定义一个成员类型
argument_type
,它可以转换为谓词的参数类型。
包装::ispunct
的最轻量级方法是使用std::reference_wrapper
:
std::find_if(s.begin(), s.end(), std::not1(std::ref(::ispunct)));
^^^^^^^^
答案 2 :(得分:-1)
其中一种方法是使用std::reference_wrapper
。这是一个示范程序
#include <iostream>
#include <functional>
#include <string>
#include <cctype>
#include <algorithm>
int main()
{
std::string s( "...hello" );
auto it = std::find_if( s.begin(), s.end(), std::not1( std::ref( ::ispunct ) ) );
std::cout << *it << std::endl;
return 0;
}
输出
h