最近项目里想用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> with
1> [
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> with
1> [
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> with
1> [
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> with
1> [
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> with
1> [
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> with
1> [
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> with
1> [
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> with
1> [
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++ 不支持默认 int
1>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> with
1> [
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> with
1> [
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> with
1> [
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> with
1> [
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> with
1> [
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;
}