C++类operator () 重载和函数对象

最近翻阅C++标准库的学习文档,看到有这样一个用法:

class CPrintInt{
  public:
    void operator() (const int& elem){
        cout<< elem << endl;
    }
};

int main(int argc, char const *argv[])
{
    vector<int> coll;
    for(int i = 1; i <= 9; ++i){
        coll.push_back(i);
    }
    for_each(coll.begin(), coll.end(), CPrintInt());
    
    return 0;
}

foreach的源码如下:

template <class _InputIterator, class _Function>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
_Function
for_each(_InputIterator __first, _InputIterator __last, _Function __f)
{
    for (; __first != __last; ++__first)
        __f(*__first);
    return __f;
}

看了上面的代码,我不禁有些蒙圈,从for_each的源码中可以看到,第三个参数是一个函数,但是我们传入的却是一个class 对象,这是什么情况?

原来,for_each函数中(当然应该不止for_each函数,类似函数应当都是如此),如果传入的是普通函数func(),则直接调用func()即可,如果传入的是“函数对象”,则调用对象的operator ();拿上面的例子来说,我们传入的CPrintInt对象是一个函数对象,for_each调用的是它的operator () 重载。

why?
感觉有点脱裤子放屁的意思,降低了代码的可读性。但是,存在肯定是有道理的,只是以我的鱼脑想不到而已。

作者给出的优点如下(以下为抄书)
1、函数对象是一种带状态(with state)的函数: 函数对象可以拥有成员变量和成员函数,且可以在运行时初始化,意味着同一个函数,执行的结果可以因对象不同而不同,这是一般函数无法做到的。
2、每个函数对象有自己的类型: 函数对象即使签名式相同,也可以有不同的类型。这样一来,我们可以将函数行为当作template参数来运行。这使得不同类型的容器可以使用同类型的函数对象作为排序准则。
3、函数对象通常比对寻常函数速度快: template概念而言,更多的细节在编译器就已确定,所以“通常可能”进行更好的优化。所以,传入一个函数对象可能获得更好的执行效能。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值