Felix Benning
Felix Benning

Reputation: 1182

Passing lambdas as a parameter in C++

I am trying to generalize my benchmarking function, by having it receive the function to benchmark as the first parameter and the number of iterations as the second.

But since the function to benchmark needs to receive additional parameters, I thought I would fill in the parameters in the body of a lambda function and pass that to the benchmarking function. (I think that is called currying?)

Anyway I can not get it to compile:

main.cpp:43:62: error: invalid initialization of non-const reference of type ‘std::function<double*()>&’ from an rvalue of type ‘main(int, char**)::<lambda()>’
   bench::bench([=](){rng::gpu_r_exp((int) 10e6, lambda);}, 50);

The function declaration looks like this:

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

and I use it like this:

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

Since the compiler bickers about non-const again, I should maybe add, that gpu_r_exp utilizes a global variable which stores the rngState (it also did not like non-const parameters in gpu_r_exp).

I am really stuck. I just want to fill in the parameters and pass the pre-prepared function handle to the benchmarking function, so that it can wrap a timer with a progress bar around it.

EDIT: I should add that the parameter called lambda is a double, which is the parameter of the exponential distribution and has nothing to do with the lambda function.

Upvotes: 0

Views: 274

Answers (1)

Given that the benchmark wrapper is small, it doesn't make sense to worry about what's passed in, or whether it can be converted to std::function. Just take what comes and as long as it can be called, you're golden:

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

If you worry that the //... sections are getting unwieldy, you can factor them out into a class:

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

Upvotes: 1

Related Questions