可以在C++\CLI中使用lambda表达式,但有一个限制,不能捕获C++\CLI托管类型,只能捕获C++的基本类型与类类型。
这很好理解,lambda是native cpp的资产,自然不认识managed code的内存和管理方式,managed code是受clr管理的。
但是可以将行参制定为托管类型,因此,仍然有可能从lambda主体内访问可托管类型。除此,与标准c++都是一样的。
如果进行捕捉,只能用gcroot或者auto_gcroot包装成普通类类型,然后捕捉这个普通类。
因为gcroot与类型T有一个成员函数可以进行隐式转换,可以进行安全的转换:
[System::Security::SecuritySafeCritical]
T operator->() const {
// gcroot is typesafe, so use static_cast
return static_cast<T>(__VOIDPTR_TO_GCHANDLE(_handle).Target);
}
�所以在例子中用(cliext::list<String^>^)gc
直接进行了转换。
ref struct persion
{
String^ name;
persion() : name(String::Empty){}
persion(String^ n) :name(n){}
bool operator < (const persion^ rhs)
{
return String::Compare(this->name,rhs->name) < 0 ? true : false;
}
};
下面是测试函数:
void test()
{
auto li = gcnew cliext::list<String ^>;
li->insert(li->begin(), "aaaa");
li->insert(li->end(), "cccc");
li->insert(li->begin(), "bbbb");
auto f0 = [](cliext::list<String ^>^ _li){
for each (String^ var in _li)
{
Console::WriteLine(var);
};
};
Console::WriteLine("call lambda with arg");
f0(li);
gcroot<cliext::list<String^>^> gc = li;
auto f = [&]()
{
std::cout << std::endl;
for each (String^ var in (cliext::list<String^>^)gc)
{
Console::WriteLine(var);
}
}
f();
li->sort();
f();
li->sort(greater<String^>());
f();
}
输出如下:
call lambda with arg
bbbb
aaaa
ccccbbbb
aaaa
ccccaaaa
bbbb
cccccccc
bbbb
aaaa
网友评论