代码之家  ›  专栏  ›  技术社区  ›  user997112

类方法,接受表示各种参数的函数的lambda

  •  2
  • user997112  · 技术社区  · 6 年前

    我想将函数传入一个泛型类方法,这样泛型类就可以调用不需要参数、一个参数、两个参数等的函数。

    我见过变量模板,但我不喜欢它的语法。前一个问题建议传递lambda,包装函数:

    https://stackoverflow.com/a/48976528/997112

    答案是:

    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中,IntelliSense检测到错误,我得到编译器错误:

    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> 类型?我不完全理解这个错误。

    2 回复  |  直到 6 年前
        1
  •  3
  •   Swordfish    6 年前

    除了邪恶的编译器扩展之外,不能初始化非常量引用(参数 func )有一些不是l值的东西。将参数设置为常量:

    #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(); });
    }
    
        2
  •  1
  •   rafix07    6 年前

    什么是 main::<lambda_de925f4d5cd926a8bb664f9c057a7a19> 类型?

    引用对lambda表达式的说明:

    lambda表达式是唯一的prvalue表达式 未命名的 非联合非聚合类类型,称为闭包类型,它是 宣布 在最小块范围内 、类作用域或命名空间作用域 包含lambda表达式的。

    仅对程序员不命名,编译器知道这个名称,在您的情况下 lambda_de925f4d5cd926a8bb664f9c057a7a19 是闭包类型的名称。 main 引用在其中定义了闭包类型的函数。

    你可以使用 cppinsights 看看幕后。 CPP洞察 使用clang,它不接受将rvalue绑定到lvalue引用,因此将代码更改为:

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

    以及 CPP洞察 是:

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