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

发布于 2024-11-17 09:30:04 字数 276 浏览 4 评论 0原文

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

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

或者

void f(auto& lambda);

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

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

What is the right way to define a function that receives a int->int lambda parameter by reference?

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

or

void f(auto& lambda);

I'm not sure the last form is even legal syntax.

Are there other ways to define a lambda parameter?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

夏见 2024-11-24 09:30:04

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

选项#1:使用 std::function 如您所示。

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

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

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

引用 lambda 时,不要忘记使用 std::forward(lambda),因为它是右值引用。

You cannot have an auto parameter. You basically have two options:

Option #1: Use std::function as you have shown.

Option #2: Use a template parameter:

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

Option #2 may, in some cases, be more efficient, as it can avoid a potential heap allocation for the embedded lambda function object, but is only possible if f can be placed in a header as a template function. It may also increase compile times and I-cache footprint, as can any template. Note that it may have no effect as well, as if the lambda function object is small enough it may be represented inline in the std::function object.

Don't forget to use std::forward<F&&>(lambda) when referring to lambda, as it is an r-value reference.

喜爱皱眉﹌ 2024-11-24 09:30:04

我将使用 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/埃伊Vq

I would use template as:

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 
}

Output:

500
1000
100

Demo : http://www.ideone.com/EayVq

瑕疵 2024-11-24 09:30:04

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

I know it's been 7 years, but here's a way nobody else mentioned:

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;});
}

Which outputs:

foo
lambda 1

No need for templates or std::function

冧九 2024-11-24 09:30:04

从 C++ 20 开始,

void f(auto& lambda);

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

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

,它相当于 @bdonlan 答案中的选项 2:

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

Since C++ 20,

void f(auto& lambda);

actually works (it's an abbreviated function template):

When placeholder types (either auto or Concept auto) appear in the parameter list of a function declaration or of a function template declaration, the declaration declares a function template, and one invented template parameter for each placeholder is appended to the template parameter list

and it's equivalent to exactly option 2 in @bdonlan's answer:

template<typename F>
void f(F &lambda) { /* ... */}
一杯敬自由 2024-11-24 09:30:04

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);
}

void f(auto& lambda);

That's close. What will actually compile is:

#include <cassert>

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

int main()
{
  int counter = 0;
  f([&]{ ++counter; });
  assert(counter == 2);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文