什么谓词,其实就是一个判断式,说白了就是一个返回bool值的函数或者仿函数。(这里说明了谓词可以有2种形式)几元就是函数有几个参数。
(1)一元谓词函数举例如下:
bool GT6(const string &s)
{
return s.size() >= 6;
}
bool Compare( int i )
{
return ( i >= 3 && i <= 8 );
}
(2)二元谓词举例如下:
bool isShorter(const string &s1, const string &s2)
{
return s1.size() < s2.size();
}
(1)定义
函数指针是指向函数的指针变量。在C编译时,每一个函数都有一个入口地址,那么这个指向这个函数的函数指针便指向这个地址。函数指针主要有两个作用:用作回调函数和做函数的参数。
(2)声明方法
前面的那个(*fun)中括号是必要的,这会告诉编译器我们声明的是函数指针而不是声明一个具有返回型为指针的函数,后面的形参要视这个函数指针所指向的函数形参而定。 然而这样声明我们有时觉得非常繁琐,于是 typedef 可以派上用场了,我们也可以这样声明:
typedef int (*pf) (int x);
pf p;
这样 p 便是一个函数指针。当要使用函数指针来调用函数时,fun(x)、(*fun)(x) 就可以了,当然,函数指针也可以指向被重载的函数,编译器会为我们区分这些重载的函数从而使函数指针指向正确的函数。
(3)使用实例:
typedef void (*P) ( char ,int );
void bar(char ch, int i) {
cout<<"bar "<
函数指针另一个作用便是作为函数的参数,我们可以在一个函数的形参列表中传入一个函数指针,然后便可以在这个函数中使用这个函数指针所指向的函数,这样便可以使程序变得更加清晰和简洁,而且这种用途技巧可以帮助我们解决很多棘手的问题,使用很小的代价就可获得足够大的利益(速度+复杂度)。
// 核心内容,非完整程序
typedef void (*P) ( char ,int );
void bar(char ch, int i) {
cout<<"bar "<
从一般的函数回调意义上来说,函数对象和函数指针是相同的,但是函数对象却具有许多函数指针不具有的有点,函数对象使程序设计更加灵活,而且能够实现函数的内联(inline)调用,使整个程序实现性能加速。此外,在我们写代码时有时会发现有些功能的实现的代码,会不断的在不同的成员函数中用到,但是又不好将这些代码独立出来成为一个类的一个成员函数。但是又很想复用这些代码。写一个公共的函数,可以,这是一个解决方法,不过函数用到的一些变量,就可能成为公共的全局变量,再说为了复用这么一片代码,就要单立出一个函数,也不是很好维护。这时就可以用仿函数了,写一个简单类,除了那些维护一个类的成员函数外,就只是实现一个operator(),在类实例化时,就将要用的,非参数的元素传入类中。这样就免去了对一些公共变量的全局化的维护了。又可以使那些代码独立出来,以便下次复用。而且这些仿函数,还可以用关联,聚合,依赖的类之间的关系,与用到他们的类组合在一起,这样有利于资源的管理(这点可能是它相对于函数最显著的优点了)。函数对象首先是一个对象,即某个类的实例。其次,函数对象的行为和函数一致,即是说可以像调用函数一样来使用函数对象,如参数传递、返回值等。这种行为是通过重载类的()操作符来实现的,如下:
class Print
{
public:
void operator()(int n)
{
std::cout<
其实我们早就开始使用函数对象了,当你写下sort(v.begin(), v.end())时(假定v是vector
template
class less
{
public:
bool operator()(const T&l, const T&r)const
{
return l < r;
}
};
在函数对象的方式中,内联incline有效,而作为函数指针时,一般编译器都不会内联函数指针指向的函数,即使指定了inline,比如:
inline bool doubleGreater(double d1, double d2)
{
return dl > d2;
}
vector v;
...
sort(v.begin(), v.end(), doubleGreater);
这个调用不是真的把doubleGreater传给sort,它传了一个doubleGreater的指针。更好的方式是使用函数对象:
sort(v.begin(), v.end(), greater())
注:《effcient c++》中的实验结论,使用函数对象一般是裸函数的1.5倍,最多能快2倍多