Home > OS >  No matching function compile error when passing lambda expression to a templated caller function?
No matching function compile error when passing lambda expression to a templated caller function?

Time:07-23

Code:

#include <iostream>

template <class FunctorType>
void caller(const FunctorType& func) {
  func();
}

int main() {
  double data[5] = {5., 0., 0., 0., 0.};
  auto peek_data = [data]() { std::cout << data[0] << std::endl; };
  auto change_data = [data]() mutable { data[0] = 4.2; };

  caller(peek_data);    // This works
  caller(change_data);  // This doesn't
  return 0;
}

If I compile this with clang -std=c 11 mutable_lambda.cpp, I got error: no matching function for call to object of type 'const (lambda at mutable_lambda.cpp:8:22)'.

Question: Why passing the second lambda expression with mutable copy capture failed to compile? Thanks in advance!

CodePudding user response:

A mutable lambda has a non-const operator(). You are trying to call this non-const operator() through a const reference. That doesn't work for the same reason that calling any non-const non-static member function doesn't work through a const reference.


If you want to allow caller to modify the passed function object (through a non-const operator() call) if it is passed as non-const argument, then take it by forwarding reference instead of const reference:

template <class FunctorType>
void caller(FunctorType&& func) {
  func(); // maybe std::forward<FunctorType>(func)();
}

Also note that change_data does not change the data in main. It changes a copy of it stored inside the lambda. If you want it to change the data in main, you need to capture data by-reference and then the lambda itself also doesn't need to be mutable anymore:

auto change_data = [&data]() { data[0] = 4.2; };
  • Related