Class 方法接受代表各种参数的函数的 lambda

Class method accepting lambdas representing functions of various number of argument

我想将函数传递给通用 class 方法,因此通用 class 可以调用不需要 args、一个 arg、两个 args 等的函数。

我见过可变参数模板,但我不喜欢这种语法。之前的 SO 问题建议传递 lambda,包装函数:

答案是:

void run_callback(std::function<void()>& func) 
{
    func();
}

run_callback([]{ func_without_params(); });

因此我添加了一个不需要参数的方法:

void func_without_params()
{
    std::cout << "x" << std::endl;
}

但是当我打电话时:

run_callback([]{ func_without_params(); });

在 VS2013 中,智能感知检测到一个错误,我得到编译器错误:

error C2664: 'void run_callback(std::function<void (void)> &)' :
cannot convert argument 1 from
'main::<lambda_de925f4d5cd926a8bb664f9c057a7a19>' to
'std::function<void (void)> &'

什么是 main::<lambda_de925f4d5cd926a8bb664f9c057a7a19> 类型?我不完全理解这个错误。

除了邪恶的编译器扩展,您不能使用非左值的东西初始化非常量引用(参数 func)。使参数常量:

#include <functional>
#include <iostream>

void run_callback(std::function<void()> const &func)
{
    func();
}

void func_without_params()
{
    std::cout << "x" << std::endl;
}

int main()
{
    run_callback([] { func_without_params(); });
}

What is a main::<lambda_de925f4d5cd926a8bb664f9c057a7a19> type?

关于 lambda 表达式的参考文献:

The lambda expression is a prvalue expression of unique unnamed non-union non-aggregate class type, known as closure type, which is declared in the smallest block scope, class scope, or namespace scope that contains the lambda expression.

unnamed 仅供程序员使用,编译器知道此名称,在您的情况下 lambda_de925f4d5cd926a8bb664f9c057a7a19 是闭包类型的名称。 main 引用定义了闭包类型的函数。

您可以使用cppinsights查看幕后情况。 cppinsights 使用不接受将右值绑定到左值引用的 Clang,因此将您的代码更改为:

void run_callback(std::function<void()> func) // take by value

并且 cppinsights 的输出是:

int main() { // scope of closure type

  class __lambda_14_16 { // closure type
    public: inline /*constexpr */ void operator()() const
    {
      func_without_params();
    }

  };

  run_callback(std::function<void ()>(__lambda_14_16{}));
}