如何将一个lambdaexpression式存储为C ++ 11中的一个类的字段?
我想创build一个类,客户端可以存储一个类似于[]() -> void {}
的lambdaexpression式作为类的字段,但我不知道如何去做。 一个答案build议使用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"); }); }
结果:
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&)
有谁知道如何做到这一点?
如果你想让一个类成员成为一个lambdaexpression式,可以考虑使用std::function<>
封装types(来自<functional>
头部),该types可以包含任何可调用的函数。 例如:
std::function<int()> myFunction = []() { return 0; } myFunction(); // Returns 0;
这样,你不需要知道lambdaexpression式的types。 您可以只存储适当函数types的std::function<>
,而模板系统将为您处理所有types。 更一般地说,即使该函数的实际types是匿名的(在lambda的情况下)或者非常复杂,任何适当签名的可调用实体都可以被分配给std::function<>
。
std::function
模板内部的types应该是与你想存储的函数相对应的函数types。 所以,例如,要存储一个接受两个int
并返回void的std::function<void (int, int)>
,你需要创build一个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. }
希望这可以帮助!
我能想到在类中存储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"); }); }