通过引用接收作为参数的 lambda 的正确方法

定义通过引用接收 int->int lambda 参数的函数的正确方法是什么?

void f(std::function< int(int) >& lambda);

或者

void f(auto& lambda);

我不确定最后一种形式是否合法。

还有其他定义 lambda 参数的方法吗?

128034 次浏览

不能有 auto参数。基本上有两个选项:

选项 # 1: 按照所示使用 std::function

选项 # 2: 使用模板参数:

template<typename F>
void f(F && lambda) { /* ... */}

在某些情况下,选项 # 2可能更有效,因为它可以避免为嵌入式 lambda 函数对象分配潜在的堆,但是只有当 f可以作为模板函数放在头中时才有可能。它还可能增加编译时间和 I-cache 内存占用,任何模板都是如此。注意,它也可能没有效果,就好像 lambda 函数对象足够小,它可以在 std::function对象中内联表示。

不要忘记在引用 lambda时使用 std::forward<F&&>(lambda),因为它是一个 r 值引用。

我将使用 template作为:

template<typename Functor>
void f(Functor functor)
{
cout << functor(10) << endl;
}


int g(int x)
{
return x * x;
}
int main()
{
auto lambda = [] (int x) { cout << x * 50 << endl; return x * 100; };
f(lambda); //pass lambda
f(g);      //pass function
}

产出:

500
1000
100

演示: http://www.ideone.com/EayVq

我知道已经过去7年了,但是有一个方法没有人提到过:

void foo(void (*f)(int)){
std::cout<<"foo"<<std::endl;
f(1); // calls lambda which takes an int and returns void
}
int main(){
foo([](int a){std::cout<<"lambda "<<a<<std::endl;});
}

产出:

foo
lambda 1

不需要模板或 std: : function

void f(auto& lambda);

很接近了,实际上要编译的是:

#include <cassert>


/*constexpr optional*/ const auto f = [](auto &&lambda)
{
lambda();
lambda();
};


int main()
{
int counter = 0;
f([&]{ ++counter; });
assert(counter == 2);
}

从 C + + 20开始,

void f(auto& lambda);

实际工作(这是一个 缩写函数模板缩写函数模板) :

当占位符类型(无论是 auto还是 Concept auto)出现在函数声明或函数模板声明的参数列表中时,声明声明一个函数模板,并且为每个占位符创建一个模板参数添加到模板参数列表中

它与@bdonlan 的回答中的选项2完全相同:

template<typename F>
void f(F &lambda) { /* ... */}