c++ 0x Lambda :在自己的项目中使用

来源:互联网 发布:线割编程留暂停点 编辑:程序博客网 时间:2024/06/01 18:55

最近项目里想用Lambda函数,但是网上找到的都是怎么在stl里使用,目前没有搜到在自己项目中使用的。经过几天的努力已经找到了使用方法,分享如下:


1.使用模板

Lambda本质上就是一个匿名的仿函数,因此模板函数里直接使用 operator ()来操作就行了

自己的模板函数:

template<class T>int lambda_test(const T& t){int i = 1234;return t(i);}
测试这个模板函数:

int ret = lambda_test([](int i)->int{return i;});//ret=1234

2.类的方法使用Lambda函数方法同上

class lambda_test2{public:template<class T>int test(const T& t){int i = 1234;return t(i);}};

测试代码:

lambda_test2 test2;int ret2 = test2.test([](int i)->int{return i;});//ret2=1234

3.使用tr1::function来传递Lambda的对象

上面使用模板来传递Lambda对象,这儿使用更普通的方法来实现:用Lambda的类型来传递

int lambda_test3(const tr1::function<int (int i)> &f){int i = 1234;return f(i);}

测试代码:

int ret3 = lambda_test3([](int i){return i;});//ret3=1234

4.如果某个类内部需要多次使用Lambda函数,则需要保存Lambda函数的对象

class lambda_test4{private:tr1::function<int (int i)> m_functor1;tr1::function<int (int i)> m_functor2;public://接收并保存lambda对象,方法1:template<class T>lambda_test4(const T& t):m_functor1(t){}//接收并保存lambda对象,方法2:void setLambda(const tr1::function<int (int i)> & f){m_functor2 = f;}int test1(){int i = 1234;return m_functor1(i);}int test2(){int j = 4567;return m_functor2(j);}};

测试代码:

lambda_test4 test4([](int i){return i;});test4.setLambda([](int i){return i*2;});int ret4 = test4.test1();int ret5 = test4.test2();//ret4:1234//ret5:9134


5.注意包含头文件:

#include <functional>using namespace std;

6.遇到的一个小问题

在使用的时候出现了如下编译错误:

1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\xxresult(28): error C2825: '_Fty': 当后面跟“::”时必须为类或命名空间1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\xxresult(40): 参见对正在编译的类 模板 实例化“std::tr1::_Result_type2<__formal,_Fty,_Arg0,_Arg1>”的引用1>          with1>          [1>              __formal=false,1>              _Fty=__w64 unsigned int,1>              _Arg0=std::tr1::_Nil &,1>              _Arg1=std::tr1::_Nil &1>          ]1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\xxresult(597): 参见对正在编译的类 模板 实例化“std::tr1::_Result_of2<_Fty,_Farg0,_Farg1>”的引用1>          with1>          [1>              _Fty=__w64 unsigned int,1>              _Farg0=std::tr1::_Nil &,1>              _Farg1=std::tr1::_Nil &1>          ]1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\xrefwrap(28): 参见对正在编译的类 模板 实例化“std::tr1::_Result_of<_Ty>”的引用1>          with1>          [1>              _Ty=__w64 unsigned int (std::tr1::_Nil &,std::tr1::_Nil &)1>          ]1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\xxbind1(273): 参见对正在编译的类 模板 实例化“std::tr1::result_of<_Fty>”的引用1>          with1>          [1>              _Fty=__w64 unsigned int (std::tr1::_Nil &,std::tr1::_Nil &)1>          ]1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\xxbind0(10): 参见对正在编译的类 模板 实例化“std::tr1::_Bind2<_Callable,_Arg0,_Arg1>::_Return<_Barg0,_Barg1,_Barg2,_Barg3,_Barg4,_Barg5,_Barg6,_Barg7,_Barg8,_Barg9>”的引用1>          with1>          [1>              _Callable=std::tr1::_Callable_obj<SOCKET,false>,1>              _Arg0=sockaddr *,1>              _Arg1=unsigned int,1>              _Barg0=std::tr1::_Nil &,1>              _Barg1=std::tr1::_Nil &,1>              _Barg2=std::tr1::_Nil &,1>              _Barg3=std::tr1::_Nil &,1>              _Barg4=std::tr1::_Nil &,1>              _Barg5=std::tr1::_Nil &,1>              _Barg6=std::tr1::_Nil &,1>              _Barg7=std::tr1::_Nil &,1>              _Barg8=std::tr1::_Nil &,1>              _Barg9=std::tr1::_Nil &1>          ]1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\functional(408): 参见对正在编译的类 模板 实例化“std::tr1::_Bind_base<_Ret,_BindN>”的引用1>          with1>          [1>              _Ret=std::tr1::_Notforced,1>              _BindN=std::tr1::_Bind2<std::tr1::_Callable_obj<SOCKET,false>,sockaddr *,unsigned int>1>          ]1>          d:\dropbox\vc\code\mhc\mhc\maindlg.cpp(598): 参见对正在编译的类 模板 实例化“std::tr1::_Bind_fty<_Fty,_Ret,_BindN>”的引用1>          with1>          [1>              _Fty=SOCKET,1>              _Ret=std::tr1::_Notforced,1>              _BindN=std::tr1::_Bind2<std::tr1::_Callable_obj<SOCKET,false>,sockaddr *,unsigned int>1>          ]1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\xxresult(28): error C2903: “result”: 符号既不是类 模板 也不是函数 模板1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\xxresult(28): error C2039: “result”: 不是“`global namespace'”的成员1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\xxresult(28): error C2143: 语法错误 : 缺少“;”(在“<”的前面)1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\xxresult(28): error C2039: “type”: 不是“`global namespace'”的成员1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\xxresult(28): error C2238: 意外的标记位于“;”之前1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\xxresult(40): error C2039: “_Type”: 不是“std::tr1::_Result_type2<__formal,_Fty,_Arg0,_Arg1>”的成员1>          with1>          [1>              __formal=false,1>              _Fty=__w64 unsigned int,1>              _Arg0=std::tr1::_Nil &,1>              _Arg1=std::tr1::_Nil &1>          ]1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\xxresult(40): error C2146: 语法错误: 缺少“;”(在标识符“_Type”的前面)1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\xxresult(40): error C4430: 缺少类型说明符 - 假定为 int。注意: C++ 不支持默认 int1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\xxresult(40): error C2602: “std::tr1::_Result_of2<_Fty,_Farg0,_Farg1>::_Type”不是“std::tr1::_Result_of2<_Fty,_Farg0,_Farg1>”基类的成员1>          with1>          [1>              _Fty=__w64 unsigned int,1>              _Farg0=std::tr1::_Nil &,1>              _Farg1=std::tr1::_Nil &1>          ]1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\xxresult(40) : 参见“std::tr1::_Result_of2<_Fty,_Farg0,_Farg1>::_Type”的声明1>          with1>          [1>              _Fty=__w64 unsigned int,1>              _Farg0=std::tr1::_Nil &,1>              _Farg1=std::tr1::_Nil &1>          ]1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\xxresult(40): error C2868: “std::tr1::_Result_of2<_Fty,_Farg0,_Farg1>::_Type”: 非法的 using 声明语法;应输入限定名1>          with1>          [1>              _Fty=__w64 unsigned int,1>              _Farg0=std::tr1::_Nil &,1>              _Farg1=std::tr1::_Nil &1>          ]1>d:\dropbox\vc\code\mhc\mhc\maindlg.cpp(598): error C2678: 二进制“==”: 没有找到接受“std::tr1::_Bind_fty<_Fty,_Ret,_BindN>”类型的左操作数的运算符(或没有可接受的转换)1>          with1>          [1>              _Fty=SOCKET,1>              _Ret=std::tr1::_Notforced,1>              _BindN=std::tr1::_Bind2<std::tr1::_Callable_obj<SOCKET,false>,sockaddr *,unsigned int>1>          ]1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\exception(470): 可能是“bool std::operator ==(const std::_Exception_ptr &,const std::_Exception_ptr &)”1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\exception(475): 或       “bool std::operator ==(std::_Null_type,const std::_Exception_ptr &)”1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\exception(481): 或       “bool std::operator ==(const std::_Exception_ptr &,std::_Null_type)”1>          c:\program files (x86)\microsoft sdks\windows\v7.0a\include\guiddef.h(192): 或       “int operator ==(const GUID &,const GUID &)”1>          c:\program files (x86)\microsoft sdks\windows\v7.0a\include\propkeydef.h(32): 或       “int operator ==(const PROPERTYKEY &,const PROPERTYKEY &)”1>          尝试匹配参数列表“(std::tr1::_Bind_fty<_Fty,_Ret,_BindN>, int)”时1>          with1>          [1>              _Fty=SOCKET,1>              _Ret=std::tr1::_Notforced,1>              _BindN=std::tr1::_Bind2<std::tr1::_Callable_obj<SOCKET,false>,sockaddr *,unsigned int>1>          ]


模板出现问题就一大堆提示,要慢慢找
解决方法:socket的bind与function的bind冲突了...,只需要把调用socket的bind(xxxx)改成:::bind(xxx)即可!!

    if (bind(m_sock, (sockaddr*)&sin, sizeof(sin)) == SOCKET_ERROR)    {        return false;    }

改为:

    if (::bind(m_sock, (sockaddr*)&sin, sizeof(sin)) == SOCKET_ERROR)    {        return false;    }


7.完整的测试代码,vc2010编译测试通过

#include <functional>using namespace std;template<class T>int lambda_test(const T& t){int i = 1234;return t(i);}class lambda_test2{public:template<class T>int test(const T& t){int i = 1234;return t(i);}};class lambda_test4{private:tr1::function<int (int i)> m_functor1;tr1::function<int (int i)> m_functor2;public://接收并保存lambda对象,方法1:template<class T>lambda_test4(const T& t):m_functor1(t){}//接收并保存lambda对象,方法2:void setLambda(const tr1::function<int (int i)> & f){m_functor2 = f;}int test1(){int i = 1234;return m_functor1(i);}int test2(){int j = 4567;return m_functor2(j);}};int lambda_test3(const tr1::function<int (int i)> &f){int i = 1234;return f(i);}int main(){int ret = lambda_test([](int i)->int{return i;});lambda_test2 test2;int ret2 = test2.test([](int i)->int{return i;});int ret3 = lambda_test3([](int i){return i;});lambda_test4 test4([](int i){return i;});test4.setLambda([](int i){return i*2;});int ret4 = test4.test1();int ret5 = test4.test2();return 0;}