116

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

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

或者

void f(auto& lambda);

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

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

4

5 回答 5

109

你不能有一个auto参数。你基本上有两个选择:

选项#1:std::function按照您的说明使用。

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

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

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

于 2011-06-23T18:11:13.223 回答
56

我会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

于 2011-06-23T18:13:33.863 回答
32

我知道已经 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

于 2019-04-27T23:32:03.203 回答
10

从 C++ 20 开始,

void f(auto& lambda);

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

当占位符类型(autoConcept auto)出现在函数声明或函数模板声明的参数列表中时,该声明声明了一个函数模板,并且每个占位符的一个发明模板参数被附加到模板参数列表

它完全等同于@bdonlan's answer中的选项2:

template<typename F>
void f(F &lambda) { /* ... */}
于 2021-05-27T08:53:21.073 回答
4

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);
}
于 2020-05-26T23:49:09.240 回答