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

lambda函数的类型是什么?

  •  8
  • Cam  · 技术社区  · 14 年前

    在C++0X中,我想知道LAMBDA函数的类型是什么。明确地:

    #include<iostream>
    
    type1 foo(int x){
     return [x](int y)->int{return x * y;};
    }
    
    int main(){
    
     std::cout<<foo(3)(4);//would output 12
    
     type2 bar = foo(5);
     std::cout<<bar(6);//would output 30
     return 0;
    }
    

    我需要用什么来代替1/2型,才能使上面的内容正常工作?希望你能看到我正在努力实现的目标,所以即使不能直接替换type1和type2,也许你能引导我朝着正确的方向前进。

    换言之:

    • 如何获取返回匿名函数的函数?
    • 如何将匿名函数赋给变量?

    谢谢!

    编辑:我正在用Visual Studio 2010编译

    2 回复  |  直到 14 年前
        1
  •  14
  •   Georg Fritzsche    14 年前

    您永远无法知道lambda函数的类型,因为在逻辑上,编译器会生成一个(本地)类,函数调用运算符重载,并且该(本地)类的数据成员表示词法闭包。这是lambda函数在逻辑上发生的情况,例如:

    auto foo = [](int x, int y) { return x + y; };
    

    编译器逻辑上这样做:

    struct CompilerGeneratedName { void operator()(int x, int y) const { return x + y; } };
    CompilerGeneratedName foo;
    

    由于编译器生成一个(本地)类,它会生成一个名称,因此您永远不能显式地写入该类型,因此您只能从模板函数参数的类型扣除或使用auto/decltype推断该类型。

    此外,C++0x闭包是静态分配的,因此无论如何都不能安全地返回原始C++0x闭包。

    尽管有几种方法可以实现这一点,但第一种方法更灵活,支持捕捉词汇范围的lambda函数。使用std::function,如果您有一个lambda函数,它没有从外部范围捕获任何内容,那么您可以使用函数指针,但是这种转换更多的是用于处理遗留代码,而不是任何东西。

    所以基本上你想要的是:

    std::function< int (int) > foo(int x)
    {
        return [x](int y)->int{return x * y;};
    }
    

    为什么我一直在逻辑地说,是因为这是如何推进:lambda类型的作品最初(即使C++ 03不允许本地类在模板函数参数中使用)和添加lambda函数的想法源自何处,但由于这是一个语言特征,现在编译器供应商可以在不同和M中实现它。更有效的方法是,当通过引用捕获所有环境时,编译器只需向调用堆栈传递一个指针,而不是以逻辑方式传递,同时仍然维护逻辑视图。

        2
  •  6
  •   sbi    14 年前

    Wikipedia :

    lambda函数是依赖于实现的类型的函数对象;此类型的名称仅对编译器可用。如果用户希望将lambda函数作为参数,则该类型必须是模板类型,或者必须创建一个 std::function 以捕获lambda值。

    VC10编译此

    //Beware, brain-compiled code ahead!
    #include<iostream>
    #include<functional>
    
    std::function<int(int)> foo(int x)
    {
        return [x](int y)->int{return x * y;};
    }
    
    int main(){
    
        std::cout<<foo(3)(4) << '\n';
    
        auto bar = foo(5);
        std::cout<<bar(6) << '\n';
    
        return 0;
    }
    

    印刷品

    12
    30