Hen*_*nke 3 c++ lambda templates c++14
免责声明: 请勿在此问题中使用该代码.它调用未定义的行为.问题的核心陈述,编译器是否为每个lambda生成一个新类型,以及相应的答案仍然有效.
要获取一个带有捕获的lambda的函数指针,我想出了以下技巧:
auto f = [&a] (double x) { return a*x; };
static auto proxy = f;
double(*ptr)(double) = [] (double x) { return proxy(x); };
// do something with ptr
Run Code Online (Sandbox Code Playgroud)
我将lambda与一个捕获(可能是一个函数参数)分配给函数内部的静态变量,所以我不必在另一个lambda中使用它时捕获它.然后另一个无捕获的lambda可以快乐地衰减到一个函数指针,我可以传递给一些共享库.
现在可以尝试概括一下:
template < typename F >
decltype(auto) get_ptr(F f)
{
static auto proxy = f;
return [] (auto ... args) { return proxy(args...); };
}
Run Code Online (Sandbox Code Playgroud)
但是,作为proxy静态变量,它将在每次调用函数时被覆盖.因为它是一个模板,我认为它只会在我调用相同的实例化时被覆盖,即每个实例化都有它自己的静态proxy.
不过,以下作品:
#include <cassert>
template < typename F >
decltype(auto) get_ptr(F f)
{
static auto proxy = f;
return [] (auto ... args) { return proxy(args...); };
}
int main()
{
auto f1 = [ ](double,double) { return 1; };
auto f2 = [=](double,double) { return 2; };
auto f3 = [&](double,double) { return 3; };
auto f4 = [&](double,double) { return 4; };
auto f5 = [ ](double,double) { return 5; };
int(*p1)(double,double) = get_ptr(f1);
int(*p2)(double,double) = get_ptr(f2);
int(*p3)(double,double) = get_ptr(f3);
int(*p4)(double,double) = get_ptr(f4);
int(*p5)(double,double) = get_ptr(f5);
assert( p1(0,0) == 1 );
assert( p2(0,0) == 2 );
assert( p3(0,0) == 3 );
assert( p4(0,0) == 4 );
assert( p5(0,0) == 5 );
}
Run Code Online (Sandbox Code Playgroud)
这看起来很可疑get_ptr(f1),get_ptr(f5)人们可能期望推断出相同的类型.但是,lambdas是编译器生成的结构,似乎编译器会为每个lambda生成不同的类型,无论之前的lambda是否可以重用.
因此,在编译器肯定会为每个lambda生成不同类型的情况下,上述技巧对我非常有用.如果不是这种情况,我的黑客的泛化就没用了.