【问题标题】:Passing lambdas as a parameter in C++在 C++ 中将 lambdas 作为参数传递
【发布时间】:2020-09-13 16:55:38
【问题描述】:

我正在尝试概括我的基准测试函数,让它接收基准函数作为第一个参数,将迭代次数作为第二个参数。

但是由于要进行基准测试的函数需要接收额外的参数,所以我想我会在 lambda 函数的主体中填写参数并将其传递给基准测试函数。 (我认为这叫做柯里化?)

无论如何我无法编译:

main.cpp:43:62:错误:从 'main(int, char**)::' bench::bench([=](){rng::gpu_r_exp((int) 10e6, lambda);}, 50);

函数声明如下所示:

void bench(std::function<double*()>& funct_to_bench, int repeats);

我是这样使用它的:

bench::bench([=](){rng::gpu_r_exp((int) 10e6, lambda);}, 50);

由于编译器再次对non-const 争论不休,我应该补充一点,gpu_r_exp 使用了一个存储rngState 的全局变量(它也不喜欢gpu_r_exp 中的非常量参数)。

我真的被困住了。我只是想填写参数并将预先准备好的函数句柄传递给基准函数,以便它可以包装一个带有进度条的计时器。

编辑:我要补充一点,叫做lambda的参数是一个double,它是指数分布的参数,与lambda函数无关。

【问题讨论】:

  • lambda 不是std::function。您需要将 std::function 传递给函数,因为它需要非常量左值引用。
  • @NathanOliver stackoverflow.com/questions/6458612/… 接受的答案说选项 1 有效,这几乎就是我使用的,对吧?
  • 您的函数使用的是std::function &amp;,这与std::function 不同。非常量左值引用(std::function &amp; 是)不允许转换。你必须准确地给出它是什么。
  • @FelixB。在void foo(int&amp;) 中,int&amp; 是非常量左值引用。在void foo(const int &amp;) 中,const int &amp; 是一个 const 左值引用。在void foo(int&amp;&amp;) 中,int&amp;&amp; 是一个右值引用。在 void foo(const int&amp;&amp;) 中,consat int&amp;&amp; 是一个 const 右值引用。
  • @FelixB。不。就像我说的:非常量左值引用不允许转换。你必须准确地给出它是什么。由于 lambda 不是 std::function 它不会工作。一个 const-lvalue 引用确实允许转换并让代码工作。

标签: c++ function lambda


【解决方案1】:

鉴于基准包装器很小,担心传入的内容或是否可以转换为std::function 是没有意义的。随遇而安,只要它可以被调用,你就是金子:

template <typename Fun>
void benchmarkCallable(size_t iterations, Fun &&callable)
{
  //...
  while (iterations--)
    callable();
  //..
}

如果您担心//... 部分变得笨拙,您可以将它们分解到一个类中:

class ScopedBenchmark {
  // start time, other state needed, etc.
public:
  ScopedBenchmark() { /* capture initial state */ }
  ~ScopedBenchmark() { /* dump results etc */ }
};

template <typename Fun>
void benchmarkCallable(size_t iterations, Fun &&callable)
{
  ScopedBenchmark benchmark;
  while (iterations--)
    callable();
}

int main()
{
  benchmarkCallable(1'000'000, []{ printf("foo!\n"); });
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-06-28
    • 1970-01-01
    • 2012-09-03
    • 2011-02-08
    • 1970-01-01
    • 2017-03-19
    • 2013-08-25
    • 2011-12-30
    相关资源
    最近更新 更多