C++ C++;从函数返回的lambda闭包类型
考虑以下示例代码:C++ C++;从函数返回的lambda闭包类型,c++,lambda,closures,c++14,C++,Lambda,Closures,C++14,考虑以下示例代码: int main() { auto id = []() { auto ret = [](auto u) { return u; }; return ret; }; //same closure type -- prints '1' auto f1 = id(); auto g1 = id(); std::cout<<std::is_same<decltype(f1),
int main()
{
auto id = []()
{
auto ret = [](auto u) { return u; };
return ret;
};
//same closure type -- prints '1'
auto f1 = id();
auto g1 = id();
std::cout<<std::is_same<decltype(f1), decltype(g1)>::value<<std::endl;
//differenct closure type -- prints '0'
auto f2 = [](auto u) { return u; };
auto g2 = [](auto u) { return u; };
std::cout<<std::is_same<decltype(f2), decltype(g2)>::value<<std::endl;
}
intmain()
{
自动id=[]()
{
auto ret=[](auto u){return u;};
返回ret;
};
//相同的闭包类型--打印“1”
自动f1=id();
自动g1=id();
std::cout我对您的(未编辑的)示例进行了一些扩展,以获得更多信息:
#include<iostream>
#include<type_traits>
#include<utility>
#include<functional>
#include<array>
#include<tuple>
#include<algorithm>
#include<string>
auto add = [](auto t)
{
auto ret = [t](auto u) { return t + u; };
return ret;
};
int main()
{
//same closure type -- prints '1'
auto f1 = add(3);
auto g1 = add(4);
auto h1 = add(1.);
std::cout<<std::is_same<decltype(f1), decltype(g1)>::value<<std::endl;
std::cout<<std::is_same<decltype(f1), decltype(h1)>::value<<std::endl;
std::cout<<typeid(f1).name() <<"\t" << typeid(g1).name()<<"\t" << typeid(h1).name()<<std::endl;
//differenct closure type -- prints '0'
auto f2 = [t{3}](auto u) { return t + u; };
auto g2 = [t{4}](auto u) { return t + u; };
std::cout<<std::is_same<decltype(f2), decltype(g2)>::value<<std::endl;
std::cout<<typeid(f2).name() << "\t" << typeid(g2).name()<<std::endl;
//using same line multiple times
std::vector<std::string> types;
for(int i=0; i<3; ++i)
types.push_back(typeid([t{i}](auto u) { return t + u; }).name());
for(auto type:types)
std::cout<<type<<std::endl;
}
对我来说,这看起来像这样:
正如您链接的答案中所述,每个lambda都有自己的类型。
但是,add()
-函数被视为一个模板,因此每个类型都有一个专门化(在我的示例中是int和float)同样的代码被执行两次-并且在像C++这样的强类型语言中,这两个代码当然会生成相同的类型。如果在循环中调用,同样会发生同样的情况。
然而,如果声明了一个lambda,那么看起来是一样的,编译器有两个(可能)不同的表达式要编译,并创建不同的类型包含在typename中,可能引用了lambda声明的作用域。好吧,您正在调用add
的operator()
…在“auto f2=[t{3}](auto u){return t+u;}中的t是什么?@Columbo:我期望如下:在调用add
的operator()时
,在主体中生成一个具有唯一类型的新的唯一闭包,并在其后返回——就像在main中一样。这种期望有什么不对?如果lambdaadd
在运行时提供循环边界的循环中被调用,会发生什么?编译器如何能够生成唯一的lambda类型循环的每个迭代都使用了es;我注意到在所有情况下与add
一起使用的类型都是int
,正如示例所示(参见初始帖子)@Niall:我得到了示例,谢谢。你说得对,这很自然:具有给定参数的成员函数有一个唯一的返回类型,而不是每次调用都有一个新的返回类型。
1
0
ZNKUlT_E_clIiEEDaS_EUlS_E_ ZNKUlT_E_clIiEEDaS_EUlS_E_ ZNKUlT_E_clIdEEDaS_EUlS_E_
0
Z4mainEUlT_E_ Z4mainEUlT_E0_
Z4mainEUlT_E1_
Z4mainEUlT_E1_
Z4mainEUlT_E1_