My first try was like this, use a helper function to forward the lambda body and store that as an private member of a class. But this is a HAS-A relationship, not really inherited from the lambda.
#include <iostream> #include <utility> template<typename lambda> class Foo { lambda _t; int x = 5566; public: Foo(lambda &&t) : _t(std::forward<lambda>(t)) { std::cout << "Foo()" << std::endl; } ~Foo() { std::cout << "~Foo()" << std::endl; } void operator()(void) { _t(x); } void operator()(int x) { std::cout << "Foo(int): " << x << std::endl; } }; template<typename lambda> Foo<lambda> make_class(lambda &&t) { return { std::forward<lambda>(t) }; } int main (void) { auto qq = make_class([](int x) -> void { std::cout << "operator(int): " << x << std::endl; }); qq(); qq(7788); return 0; }
Foo()
operator(int): 5566
Foo(int): 7788
~Foo()
suhorngT improved this as a real inheritance:
#include <iostream> #include <utility> template<typename lambda> class Foo : public lambda { public: Foo(lambda &&t) : lambda(t) { std::cout << "Foo()" << std::endl; } ~Foo() { std::cout << "~Foo()" << std::endl; } }; template<typename lambda> Foo<lambda> make_class(lambda &&t) { return { std::forward<lambda>(t) }; } int main (void) { auto qq = make_class([](int x) -> void { std::cout << "operator(int): " << x << std::endl; }); qq(123); return 0; }
Foo()
operator(int): 123
~Foo()
After that I took out the make_class helper, and use decltype instead, make the syntax much better.
#include <iostream> template<typename... lambda> class Bar : public lambda... { public: Bar(lambda... l) : lambda(l)... { std::cout << "Bar()" << std::endl; } void foo(void) { std::cout << "foo()" << std::endl; } }; int main(void) { int a = 55; auto gg = [a](int b) -> void { std::cout << "operator(): " << a << b << std::endl; }; auto qq = Bar<decltype(gg)>(gg); qq(66); qq.foo(); return 0; }
Bar()
operator(): 5566
foo()
Reference:
http://cpptruths.blogspot.tw/2014/05/fun-with-lambdas-c14-style-part-2.html
http://cpptruths.blogspot.com/2014/03/fun-with-lambdas-c14-style-part-1.html