如何在C ++ 11/14中实例化Lambda闭包类型?

The*_*ist 11 c++ performance lambda closures c++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;
}
Run Code Online (Sandbox Code Playgroud)

由于性能原因,我不能std::function避免使用虚拟指针调用。有没有办法做到这一点?我需要实例化该lambda一次,并在该函数中多次使用它。

当将标准库decltype(myLambda)传递给std::maptemplate参数中的比较器之类的东西时,标准库如何使其工作?

Nik*_* C. 7

尽管C ++ 20中提供了此功能(请参见songyuanyao的答案),但是在这种情况下,您实际上并不需要此功能。您可以将lambda作为类型的函数参数传递,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);
}
Run Code Online (Sandbox Code Playgroud)


son*_*yao 5

我知道lambda闭包类型没有默认的构造函数。

是的,在C ++ 20之前都是如此。(请注意,由于C ++ 20如果未指定捕获,则闭包类型具有默认的默认构造函数。)

闭包类型不是DefaultConstructible。闭包类型具有a deleted (until C++14) no (since C++14)默认构造函数。(直到C ++ 20)

当将标准库decltype(myLambda)传递给std::maptemplate参数中的比较器之类的东西时,标准库如何使其工作?

标准库没有什么特别的。如果您将非DefaultConstructible lambda指定为的比较器类型std::map,则必须将一个对象传递给构造函数,std::map它将通过复制来初始化其比较器;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));
}
Run Code Online (Sandbox Code Playgroud)

然后

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);
Run Code Online (Sandbox Code Playgroud)

生活