如何将lambda表达式存储为C++ 11中的类的字段?

46 c++ lambda field class c++11

我想创建一个类,其中客户端可以存储lambda表达式,如类[]() -> void {}的字段,但我无法弄清楚如何这样做. 一个答案建议使用decltype,我尝试没有成功.这是一个ideone源链接.以下是来源和结果:

#include <cstdio>
auto voidLambda = []()->void{};

class MyClass {
public:
     decltype(voidLambda) t;
     MyClass(decltype(voidLambda) t) { 
        this->t = t;
     }
};

int main() {
   MyClass([] {
      printf("hi");
   });
}
Run Code Online (Sandbox Code Playgroud)

结果:

prog.cpp: In constructor 'MyClass::MyClass(<lambda()>)':
prog.cpp:3:79: error: no matching function for call to '<lambda()>::__lambda0()'
prog.cpp:2:20: note: candidates are: <lambda()>::<lambda>(const<lambda()>&)
prog.cpp:2:20: note:                 <lambda()>::<lambda>(<lambda()>&&)
prog.cpp:3:88: error: no match for 'operator=' in '((MyClass*)this)->MyClass::t = t'
prog.cpp: In function 'int main()':
prog.cpp:5:27: error: no matching function for call to 'MyClass::MyClass(main()::<lambda()>)'
prog.cpp:3:48: note: candidates are: MyClass::MyClass(<lambda()>)
prog.cpp:3:14: note:                 MyClass::MyClass(const MyClass&)
Run Code Online (Sandbox Code Playgroud)

有谁知道如何做到这一点?

tem*_*def 48

如果您希望类成员是lambda表达式,请考虑使用std::function<>包装类型(来自<functional>标头),它可以包含任何可调用函数.例如:

std::function<int()> myFunction = []() { return 0; }
myFunction(); // Returns 0;
Run Code Online (Sandbox Code Playgroud)

这样,您不需要知道lambda表达式的类型.您可以只存储std::function<>适当的函数类型,模板系统将为您处理所有类型.更一般地std::function<>,即使该仿函数的实际类型是匿名的(在lambdas的情况下)或者非常复杂,也可以将适当签名的任何可调用实体分配给a .

std::function模板内部的类型应该是与您要存储的函数对应的函数类型.因此,例如,要存储一个接收两个ints并返回void 的函数,你就可以创建一个std::function<void (int, int)>.对于不带参数并返回的函数int,您可以使用std::function<int()>.在你的情况下,因为你想要一个不带参数和返回的函数void,你需要这样的东西:

class MyClass { 
public:
    std::function<void()> function;
    MyClass(std::function<void()> f) : function(f) {
        // Handled in initializer list
    }
};

int main() {
    MyClass([] {
        printf("hi")
    }) mc; // Should be just fine.
}
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助!

  • 为什么人们不在他们的答案中包含相关的内容?这将拯救我这么多谷歌搜索! (2认同)

cub*_*l42 11

我能想到将lambda存储在类中的唯一方法是使用带辅助make_函数的模板:

#include <cstdio>
#include <utility>

template<class Lambda>
class MyClass {
    Lambda _t;
public:
    MyClass(Lambda &&t) : _t(std::forward<Lambda>(t)) {
        _t();
    }
};

template<class Lambda>
MyClass<Lambda> make_myclass(Lambda &&t) {
    return { std::forward<Lambda>(t) };
}

int main() {
    make_myclass([] {
        printf("hi");
    });
}
Run Code Online (Sandbox Code Playgroud)

  • 通过引入这个帮助程序`make_myclass`来避免指定模板参数的需要.那就是[Object generator idiom](https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Object_Generator). (6认同)