[英]How can I instantiate a lambda closure type in C++11/14?
我知道 lambda闭包类型没有默认构造函数。 但这是否意味着在作为模板参数传递之后无法实例化它?
请考虑以下最小示例 :
#include <iostream>
template <typename FuncType>
std::pair<int,int> DoSomething() {
return FuncType()(std::make_pair(1,1));
}
int main() {
auto myLambda = [](std::pair<int,int> x) {
return std::make_pair(x.first*2,x.second*2);
};
std::pair<int,int> res = DoSomething<decltype(myLambda)>();
return 0;
}
出于性能原因, 我不能使用std::function
来避免虚拟指针调用。 有没有办法做到这一点? 我需要实例化一次lambda并在该函数内多次使用它。
当decltype(myLambda)
传递给模板参数中的std::map
comparators之类的东西时,标准库如何使它工作?
虽然这个功能将在C ++ 20中出现(参见songyuanyao的回答),但在这种情况下你实际上并不需要。 您可以将lambda作为FuncType
类型的函数参数FuncType
并多次调用:
template <typename FuncType>
std::pair<int,int> DoSomething(FuncType f)
{
return f(std::make_pair(1,1));
}
int main()
{
auto myLambda = [](std::pair<int,int> x) {
return std::make_pair(x.first*2,x.second*2);
};
std::pair<int,int> res = DoSomething(myLambda);
}
我知道lambda闭包类型没有默认构造函数。
是的,直到C ++ 20才是这样。 (注意,由于C ++ 20没有指定捕获,因此闭包类型具有默认的默认构造函数。)
闭包类型不是DefaultConstructible。 Closure类型有
a deleted (until C++14)
no (since C++14)
默认构造函数。 (直到C ++ 20)
和
当
decltype(myLambda)
传递给模板参数中的std::map
comparators之类的东西时,标准库如何使它工作?
标准库没有什么特别之处。 如果指定一个非DefaultConstructible lambda作为std::map
的比较器类型,则必须将一个对象传递给构造函数, std::map
将通过copy初始化其比较器; lambda有复制和移动构造函数。
您可以将代码更改为与std::map
的构造函数相同的方式:
template <typename FuncType>
std::pair<int,int> DoSomething(const FuncType& f = FuncType()) {
// auto z(f); // you can take a copy if necessary
return f(std::make_pair(1,1));
}
然后
auto myLambda = [](std::pair<int,int> x) {
return std::make_pair(x.first*2,x.second*2);
};
std::pair<int,int> res = DoSomething<decltype(myLambda)>(myLambda);
正如其他人所指出的那样,空的lambda将在C ++ 20中成为默认构造。
你不能等待/切换到它?
没问题,只要你的lambda不是通用的,它就很容易模拟。
只需将lambda转换为函数指针,并将其打包成std::integral_constant
:
template <class T>
constexpr auto make_constant(T t) noexcept
-> std::integral_constant<decltype(+t), +t>
{ return {}; }
当然,在大多数可以选择函数对象类型的情况下,您也可以传递初始值,这样更容易一些。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.