将 lambda 表达式传递给模板化调用函数时,没有匹配的函数编译错误?

aar*_*nfu 7 c++ lambda templates capture

代码:

#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;
}
Run Code Online (Sandbox Code Playgroud)

如果我用 编译它clang++ -std=c++11 mutable_lambda.cpp,我得到了 error: no matching function for call to object of type 'const (lambda at mutable_lambda.cpp:8:22)'

问题:为什么通过可变副本捕获传递第二个 lambda 表达式无法编译?提前致谢!

use*_*522 7

lambdamutable有一个非const operator(). 您试图const operator()通过引用来称呼它const。这不起作用,其原因与调用任何非非const静态成员函数不能通过const引用起作用相同。


如果您希望允许caller修改传递的函数对象(通过非const operator()调用)(如果它作为非const参数传递),则通过转发引用而不是const引用来获取它:

template <class FunctorType>
void caller(FunctorType&& func) {
  func(); // maybe std::forward<FunctorType>(func)();
}
Run Code Online (Sandbox Code Playgroud)

另请注意,change_data不会更改datain main。它会更改存储在 lambda 中的副本。如果您希望它更改datain main,则需要data通过引用捕获,然后 lambda 本身也不再需要mutable

auto change_data = [&data]() { data[0] = 4.2; };
Run Code Online (Sandbox Code Playgroud)