笔者这里用一个简单的代码片段来说明伪函数的实现和用法,及其优点。代码示例如下:
class Abs
{
public:
int operator()(int num)const; //这个操作符的重载是实现伪函数的关键
Abs();
void setIsOpponent(bool isOpponent);
private:
bool isOpponent;
};
//关键方法
int Abs::operator()(int num)const
{
int res;
if(!isOpponent)
{
res = num > 0 ? num : -num;
}
else
{
res = num > 0 ? -num : num;
}
return res;
}
Abs::Abs()
{
isOpponent = false;
}
void Abs::setIsOpponent(bool aIsOpponent)
{
isOpponent = aIsOpponent;
}
我们可以看到,由于Abs类实现了一个"()"操作符,这样就允许把这个类像函数一样使用。
我们把这样的类称为函数对象,或称做伪函数。
使用示例如下:
Abs myAbs;
myAbs.setIsOpponent(true); //进行相反操作。
int value = myAbs(-23); //这里如同把myAbs实例当作一个函数来使用。
优点:使用仿函数就像使用一个普通的函数一样,但是它的实现可以访问仿函数中所有的成员变量来进行通行;而普通函数若要通信就只能依靠全局变量了。
(http://blog.chinaunix.net/u3/90609/showart_1811637.html)
Bjarne: 什么是函数对象?
顾名思义,就是在某种方式上表现的象一个函数的对象。典型的,它是指一个类的实例,这个类定义了应用操作符operator()。
函数对象是比函数更加通用的概念,因为函数对象可以定义跨越多次调用的可持久的部分(类似静态局部变量),同时又能从对象的外面进行初始化和检查(和静态局部变量不同)。例如:
class Sum
{
int val;
public:
Sum(int i):val(i) {}
operator int() const { return val; } // 取得值
int operator()(int i) { return val+=i; } // 应用
};
void f(vector v)
{
Sum s = 0; // initial value 0
s = for_each(v.begin(), v.end(), s); // 求所有元素的和
cout << "the sum is " << s << "/n";
//或者甚至:
cout << "the sum is " << for_each(v.begin(), v.end(), Sum(0)) << "/n";
}
注意:一个拥有应用操作符的函数对象可以被完美地内联化(inline),因为它没有涉及到任何指针,后者可能导致拒绝优化。与之形成对比的是,现有的优化器几乎不能(或者完全不能?)将一个通过函数指针的调用内联化。
在标准库中,函数对象被广泛的使用以获得弹性。
(http://hi.baidu.com/ilotus_y/blog/item/7a1044d3b23f6fdaa9ec9a87.html)