STL算法的函数有时候需要传递函数,可以传递函数指针,函数对象(函数符)、lambda表达式。

计算vector数组中能被3和13整除数的个数。

传入普通函数

bool f3(int x){
    return x%3==0;
}
bool f13(int x){
    return x%13==0;
}
int count3 = count_if(numbers.begin(),numbers.end(),f3);
int count13 = count_if(numbers.begin(),numbers.end(),f13);
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.

函数对象:()操作符重载可以当成一个函数使用,但是不如lambda函数好用。

class f_mod{
   private:
      int dv;
   public:
      f_mod(int d=1):dv(d){}
      bool operator() (int x){return x%dv==0;}
};


//函数对象
count3 = count_if(numbers.begin(),numbers.end(),f_mod(3));
count13 = count_if(numbers.begin(),numbers.end(),f_mod(13));
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.

 lamda函数:

//匿名函数
count3 = count_if(numbers.begin(),numbers.end(),[](int x){return x%3==0;});
count13 =count_if(numbers.begin(),numbers.end(),[](int x){
        return x%13==0;
});
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

[ ]替代了函数名,没有声明函数类型,如果函数只有一行,自动推导类型,否则指出类型。

[](double x)->double{int y=x;return x-y;}
  • 1.

为什么使用lambda?

函数位于调用的地方近,便于查看和修改,很方便。

效率上,lambbda函数可以自动优化为内联函数,但是使用函数指针不会优化为内联函数。

功能上,[&变量]可以应用变量,[&]可以引用所有动态变量,[=]可以按值引用所有动态变量。

for_each(numbers.begin(),numbers.end(),
      [&count13](int x){count13+=x%13==0;}
    );
  • 1.
  • 2.
  • 3.