码迷,mamicode.com
首页 > 编程语言 > 详细

[c++] Callable Objects

时间:2016-12-14 18:57:14      阅读:320      评论:0      收藏:0      [点我收藏+]

标签:strong   函数指针   size   抽象   color   数学   family   不能   cal   

Five kinds of callable objects:

  1. Functions
  2. Pointers to functions
  3. Objects of a class that overloads ()
  4. Objects created by bind
  5. Objects created by lamdba expressions

 


1-2. Functions and Pointers to functions

    bool range5to10(int val)  // <-- bool (*p_func)(int) 改为函数指针是一个道理
{
   return (5 <= val && val <= 10);
}


vector<int> vec{ 20, 2, 4, 3, 8, 10, 15, 1}; auto presult = find_if(vec.begin(), vec.end(), range5to10); if (presult == vec.end()) { cout << "no" << endl; } else { cout << "yes" << endl; }

 

更高逼格的template,至少能在类型上更加灵活一些。

template <class T, T lb, T ub>
struct range {
    bool operator() (T val) {
        return (lb <=val && val <=ub);
    }
};

auto presult = find_if(vec.begin(), vec.end(), range<int, 5, 10>{});

 

3. Object of class

class range {
public:
    range(int l, int u): lb(l), ub(u) {  // <-- 这里的构建函数的使用体现了其优势:初始化能多做些事情
    }

    bool operator() (int val) {
        return (lb <=val && val <=ub);
    }

private:
    int lb, ub;
};


auto presult = find_if(vec.begin(), vec.end(), range{5, 10});

 

思考:对比模板与类两种方式,可见高大上的模板并非浪得虚名。

void f(int a, int b, int c)
{
    cout << a << " " << b << " " << c << endl;
}

auto g1 = bind(f, placeholders::_1, placeholders::_2, 100);
g1(1, 2); 

 

 


4. Bind

// 类的构建函数的初始化参数的一种类似的方式
class
range { public: bool operator() (int lb, int ub, int val) { return (lb <=val && val <=ub); } }; auto presult = find_if(vec.begin(), vec.end(), bind(range{}, 5, 10, placeholders::_1));   //placeholders::_1 here可能代表val,暂不懂

 

When bind1st, 10绑定了greater()的第一个参数。

When bind2st, 10绑定了greater()的第二个参数。

template <class T> struct greater {
  bool operator() (const T& x, const T& y) const {return x>y;}
  typedef T first_argument_type;
  typedef T second_argument_type;
  typedef bool result_type;
};

 

技术分享

Result: c1 = 5, c2 = 2;

 

 

#include<functional> 

技术分享

一眼望去,就是模板函数的样子。

 

not1(op)

not2(op)

两个要屌炸天的函数,详见链接。

 

 


5. Lambda Functions 

<functional>的本质是什么?如下:

技术分享

 

“Lambda 表达式”(lambda expression)是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象(lambda abstraction),是一个匿名函数,即没有函数名的函数。

Lambda表达式可以表示闭包(注意和数学传统意义上的不同)。 

 

例子:(有点inline的意思)

技术分享

 

由于Lambda的类型是唯一的,不能通过类型名来显式声明对应的对象,但可以利用auto关键字和类型推导:

auto f=[](int a,int b){return a>b;};

 

** 捕获 **
auto f = [x](int a,int b){return a>x;});//x被捕获复制 int x=0,y=1; auto g = [&](int x){return ++y;});//y被捕获引用,调用g后会修改y,需要注意y的生存期 (y是返回值)

** 未捕获 ** bool(*fp)(int,int) = [](int a,int b){return a>b;});//不捕获时才可转换为“函数指针”

 

[c++] Callable Objects

标签:strong   函数指针   size   抽象   color   数学   family   不能   cal   

原文地址:http://www.cnblogs.com/jesse123/p/6179805.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!