实验小结

1)function 是一个模板类。有函数指针成员。可以看作安全型函数指针。

template<typename _Res, typename... _ArgTypes> 
class function<_Res(_ArgTypes...)> : public _Maybe_unary_or_binary_function<_Res, _ArgTypes...>,private _Function_base{

private:

typedef _Res (*_Invoker_type)(const _Any_data&, _ArgTypes...);

_Invoker_type _M_invoker;

}

2)空function。调用会抛出异常。

3)可以接受普通函数、Lambda表达式、函数指针、以及其它函数对象。

并可以把防函数为参数构成的function对象传递给一个函数指针。而放函数是不能直接给函数指针的。

 4)bind 猜测是根据一个函数声明,转为一个防函数。好处就是放函数本质是一个类。可以保存数据成员。达到一些其他目的。

5)bind 使用placeholder这些是重载函数的参数。没有占位,而直接输入的是函数的数据成员。这样bind就可以返回一个防函数的对象了。

6)而function是可以接受放函数的。当然也可以接受bind的返回值了。

 7)bind加上function。就可以让一个函数转换为一个放函数对象,并转为function类型。而function类型的特性。可以放到任何需要函数指针的地方。完美!

#include <iostream>
#include <sstream>
#include <vector>
#include <algorithm>
#include <functional> using namespace std; bool big5(int a)
{
if(a>)
{
return true;
}
else
{
return false;
}
} int GreaterInt(vector<int>::const_iterator start,vector<int>::const_iterator end,int compareInt)
{
int ret=;
for(start; start!=end; ++start)
{
if(*start>compareInt)
{
++ret;
}
}
return ret;
} int LessInt(vector<int>::const_iterator start,vector<int>::const_iterator end,int compareInt)
{
int ret=;
for(start; start!=end; ++start)
{
if(*start<compareInt)
{
++ret;
}
}
return ret;
} int ComplexLogic(vector<int>::const_iterator start,vector<int>::const_iterator end)
{
int ret=;
for(start; start!=end; ++start)
{
if(*start>&&*start!=)
{
++ret;
}
}
return ret;
} typedef bool(* FunMycompare)(int);
bool ComplexLogic2(int value);
template<typename T>
int Count_bool(vector<int>::const_iterator start,vector<int>::const_iterator end,T myfun)
{
int ret=;
for(start; start!=end; ++start)
{
if(myfun(*start))
{
++ret;
}
}
return ret;
} int Count_bool2(vector<int>::const_iterator start,vector<int>::const_iterator end,FunMycompare myfun)
{
int ret=;
for(start; start!=end; ++start)
{
if(myfun(*start))
{
++ret;
}
}
return ret;
} bool Greater5(int value)
{
if(value>)
{
return true;
}
else
{
return false;
}
} bool GreaterSmart(int value,int value2)
{
if(value>value2)
{
return true;
}
else
{
return false;
}
} bool Less5(int value)
{
if(value<)
{
return true;
}
else
{
return false;
}
} //函数指针重载问题.改名
bool ComplexLogic2(int value)
{
if(value>&&value!=)
{
return true;
}
else
{
return false;
}
} bool errorLess5(int value,int abc)
{
if(abc<)
{
return true;
}
else
{
return false;
}
} class GreaterFactor
{
public:
GreaterFactor(int value):compareInt(value) {}
bool operator()(int value)
{
if(value>compareInt)
{
return true;
}
else
{
return false;
}
}
int compareInt;
}; int main()
{
vector<int> intContainer;
for (int i = ; i <= ; ++i)
{
intContainer.push_back(i);
}
cout<<"*********normal funtions ****************************";
// 查找元素值大于某值的元素的个数
cout<<GreaterInt(intContainer.begin(),intContainer.end(),)<<endl; // 查找元素值小于某值的元素的个数
cout<<LessInt(intContainer.begin(),intContainer.end(),)<<endl; // 查找元素值大于5,且不等于8个数
cout<<ComplexLogic(intContainer.begin(),intContainer.end())<<endl; //问题来了.针对元素,求bool值的需求,越来越多. >=,<= >,< !=,=..甚至是什么比如>5&&!=8,等一些逻辑组合.
//这里因为函数代码不多,当然每个需求都写一个方法没什么大问题.
//但这些函数可以发现有共同的代码.就是遍历逻辑.假设这里不是遍历而是一个非常复杂的代码段,而且会有改动的情况.
//所以只要这个逻辑有改动的时候,就需要在所有的函数中修改,就非常辛苦和容易出错.
//所以,首先反应是,保留相同逻辑代码.把不同的逻辑代码找出来,用抽象接口代替,
//c++的抽象接口方式,还是c的函数指针.
//这里抽象为的函数原型为:typedef bool(* FunMycompare)(int);
//因为需求太多,有2参,有3参,或者更多.所以干脆,抽象为1参,也就是值保留了遍历元素时,元素本身的值. cout<<"******************call back()********************************************"<<endl;
cout<<Count_bool(intContainer.begin(),intContainer.end(),Greater5)<<endl;
cout<<Count_bool(intContainer.begin(),intContainer.end(),Less5)<<endl;
cout<<Count_bool(intContainer.begin(),intContainer.end(),ComplexLogic2)<<endl; //好处有了,就是隔离了变化.有新的需求.就只要写一个bool函数就好了.把函数名当作函数指针作为算法Count_bool的参数.
//但Greater5明显没有之前的GreaterInt好用,
//有一个防函数的东西.配合模板,刚好可以用到这里.就是对一个类重载,他的实例使用()符号的逻辑.让一个对象可以有,obj(a,b)这样像函数一样的操作.对象行为像函数指针.
//而类可以有成员数据.所以初始化的时候,可以把必要数据存储.再想想有什么替代办法.
//实在不喜欢操作符重载.别的语言是越来越直观,c++感觉基础操作就设置了太多坑.简洁但不能让人误解和性能不降低,否则这简洁没意思. //要把int Count_bool(vector<int>::const_iterator start,vector<int>::const_iterator end,T myfun)改为模板.才能不在乎你是函数指针还是防函数.
//因为模板是代码生成器,会为不同那个的参数类型,静态生成各自的代码.
//cout<<Count_bool(intContainer.begin(),intContainer.end(),GreaterFactor(8))<<endl; cout<<"******************call back(error convertion & test fun)********************************************"<<endl;
//强转造成类型不安全.
cout<<Count_bool(intContainer.begin(),intContainer.end(),(FunMycompare)errorLess5)<<endl;
//但是修改为模板也可以强转啊. //看下functional //template<typename _Res, typename... _ArgTypes>
// class function<_Res(_ArgTypes...)>
// : public _Maybe_unary_or_binary_function<_Res, _ArgTypes...>,
// private _Function_base
// { // private:
// typedef _Res (*_Invoker_type)(const _Any_data&, _ArgTypes...);
// _Invoker_type _M_invoker;
// return 0;
//其实就是定义了一个函数指针类型.跟原来的 typedef bool(* FunMycompare)(int); 是一样的.
typedef function<bool(int)> FunMycompareSafe;
FunMycompareSafe safeGreater5=Greater5; //测试一下,ok.
cout<<Count_bool(intContainer.begin(),intContainer.end(),safeGreater5)<<endl;
//在测试一下强壮.
FunMycompareSafe safeErrorGreater5=(FunMycompare)errorLess5;
cout<<Count_bool(intContainer.begin(),intContainer.end(),safeErrorGreater5)<<endl;
//...没看出来function的安全在哪里.强转也还是可以编译通过.这个....
//应该是强转就已经转为了合法的原型.所以function无法判断.那么原来的函数指针不安全到底在哪里?
//空指针?测试一下. //o.这里编译通过.但运行是肯定出错. //类型安全个鬼啊.只是抛出了异常而已.不是编译期安全.
// FunMycompare emptyPFun=0;
// try
// {
// cout<<Count_bool(intContainer.begin(),intContainer.end(),emptyPFun)<<endl;
// }
// catch(exception& e)
// {
// cout<<e.what()<<endl;
// } FunMycompareSafe emptyPfun2=;
try
{
cout<<Count_bool(intContainer.begin(),intContainer.end(),emptyPfun2)<<endl;
}
catch(exception& e)
{
cout<<e.what()<<endl;
} cout<<"functional***pointer of funtion******************************"<<endl;
function<bool(int)> ill_safeGreater5=Greater5;
function<bool(int)> ill_safeLess5=Less5;
function<bool(int)> ill_safeComplexLogic=ComplexLogic2; cout<<Count_bool(intContainer.begin(),intContainer.end(),ill_safeGreater5)<<endl;
cout<<Count_bool(intContainer.begin(),intContainer.end(),ill_safeLess5)<<endl;
cout<<Count_bool(intContainer.begin(),intContainer.end(),ill_safeComplexLogic)<<endl; cout<<"*****class function******************************"<<endl;
GreaterFactor goodFun=GreaterFactor(); //方法模板可以接受防函数.
cout<<Count_bool(intContainer.begin(),intContainer.end(),goodFun)<<endl; //error,强类型普通方法,不接受方函数.类型不一致.
//cout<<Count_bool2(intContainer.begin(),intContainer.end(),goodFun)<<endl; //强类型普通方法,接受function 对象.就像funtion的实参是一个方函数.
function<bool(int)> testclassfun=goodFun;
cout<<Count_bool(intContainer.begin(),intContainer.end(),testclassfun)<<endl; //o~~~~, function 的特性终于体现出来了.可以装载防函数.
//并且可以把防函数转为普通的函数指针. //没有仔细看bind的大概实现.主要作用,可以不用手工写一个仿函数了.
//推测大概作用就是生成一个仿函数的对象.
//就是把一个函数变成方函数,占位符就是防函数的重载括号内的参数,而输入的值就是方函数的数据成员.
//猜测bind返回一个方函数.而function是可以接受一个方函数的.所以bind可以给function.
//因为function.可以直接给函数指针.
auto bindfunc1=bind(GreaterSmart,placeholders::_1,);
function<bool(int)> testclassfun22=bindfunc1;
cout<<Count_bool2(intContainer.begin(),intContainer.end(),bindfunc1)<<endl; }

c++11 function bind 测试。的更多相关文章

  1. Using C++11 function & bind

    The example of callback in C++11 is shown below. #include <functional> void MyFunc1(int val1, ...

  2. C++ 11: function & bind 使用示例

    #include <functional> #include <iostream> struct Foo { Foo(int num) : num_(num) {} void ...

  3. C++ 类的成员函数指针 ( function/bind )

    这个概念主要用在C++中去实现"委托"的特性. 但现在C++11 中有了 更好用的function/bind 功能.但对于类的成员函数指针的概念我们还是应该掌握的. 类函数指针 就 ...

  4. 为什么React事件处理函数必须使用Function.bind()绑定this?

    最近在React官网学习Handling Events这一章时,有一处不是很明白.代码如下: class Toggle extends React.Component { constructor(pr ...

  5. 【转帖】漫话C++0x(四) —- function, bind和lambda

    实在是觉得此文总是去翻感觉不太好.于是果断转过来了,想看原文的请戳:http://www.wuzesheng.com/?p=2032 本文是C++0x系列的第四篇,主要是内容是C++0x中新增的lam ...

  6. ES6下的Function.bind方法

    在JavaScript的使用中,this的指向问题始终是一个难点.不同的调用方式,会使this指向不同的对象.而使用call,apply,bind等方式,可改变this的指向,完成一些令人惊叹的黑魔法 ...

  7. Extjs使用Ext.function.bind, 给句柄函数传参

    回调函数updateImage中的key参数,在外部调用时有程序员自己指定. 使用Ext.Function.bind(this.updateImage, this, 'imageUrl', true) ...

  8. javascript 中 function bind()

    Function bind() and currying <%-- All JavaScript functions have a method called bind that binds t ...

  9. 学习C++11的一些思考和心得(1):lambda,function,bind和委托

     1.lambda表达式 lanbda表达式简单地来讲就是一个匿名函数,就是没有名称的函数,如果以前有接触过python或者erlang的人都比较熟悉这个,这个可以很方便地和STL里面的算法配合 st ...

随机推荐

  1. 屌丝程序员的梦想 (六) 我也写个开源CMS

    离开上家公司之后,我没急着找下家公司,一直以来都是为公司做各个细小的功能却没有属于自己的完整的项目 思来想去,我准备用自己熟悉的thinkphp 和 extjs写一个开源的cms,从用户系统,文章系统 ...

  2. html标签分两种:块状元素和内联元素

      块状元素一般是其它元素的容器,可以容纳内联元素和其它块状元素,独占一行,宽度和高度起作用.如div,p等标签属于块状元素.     内联元素只能容纳文本和其它内联元素,可与其它内联元素位于同一行, ...

  3. C++之动态数组

    C99支持一种名为变长数组的结构来方便程序员.C++也提供了一种长度可在程序运行时确定的数组类型:动态数组.声明格式为:(声明 int 类型的数组) ; //此处可修改 ArraySize 的值 in ...

  4. [liusy.api-SMJ]-MAVEN archetype 创建项目

    •选择或创建工作空间 Select a workspace –File – Switch Workspace - other

  5. wamp多网站配置for window 本地测试 单Ip

    网上有很多WAMP集成环境下单IP多域名虚拟主机配置的文章,自己总结了有用方法记录下来 简单的介绍一下我的系统环境:window xp  和 wamp apache2.2.8 ------------ ...

  6. 【转】PowerShell入门(十一):编写脚本模块

    转至:http://www.cnblogs.com/ceachy/archive/2013/03/08/PowerShell_Script_Module.html 现在通过编写模块就可以在PowerS ...

  7. 170104、js内置对象与原生对象

    内置对象与原生对象 内置(Build-in)对象与原生(Naitve)对象的区别在于:前者总是在引擎初始化阶段就被创建好的对象,是后者的一个子集:而后者包括了一些在运行过程中动态创建的对象. 原生对象 ...

  8. memcache基础知识

    memcached的内存存储机制 Memcached默认情况下采用了名为Slab Allocator的机制分配.管理内存.在该机制出现以前,内存的分配是通过对所有记录简单地进行malloc和free来 ...

  9. STM32下FatFs的移植,实现了坏块管理,硬件ECC,ECC纠错,并进行擦写均衡分析

    最近因项目需要,做一个数据采集的单片机平台.需要移植 FatFs .现在把最后成果贴上来. 1.摘要 在 STM32 单片机上,成功移植 FatFs 0.12b,使用的 Nand Flash 芯片为 ...

  10. MySQL 各种超时参数的含义

    MySQL 各种超时参数的含义 今日在查看锁超时的设置时,看到show variables like '%timeout%';语句输出结果中的十几种超时参数时突然想整理一下,不知道大家有没有想过,这么 ...