fork download
  1. #include <new>
  2. #include <type_traits>
  3. #include <utility>
  4.  
  5. template <typename F>
  6. struct RAIIFunctor {
  7. typedef typename std::remove_reference<F>::type functor_type;
  8.  
  9. typename std::aligned_storage<sizeof(functor_type),
  10. std::alignment_of<functor_type>::value>::type store;
  11.  
  12. functor_type* f;
  13.  
  14. RAIIFunctor() : f{nullptr} {}
  15. ~RAIIFunctor() { destroy(); }
  16.  
  17. template <class T>
  18. void assign(T&& t) {
  19. destroy();
  20. f = new(&store) functor_type {std::forward<T>(t)};
  21. }
  22.  
  23. void destroy() {
  24. if (f)
  25. f->~functor_type();
  26. f = nullptr;
  27. }
  28.  
  29. void operator()() {
  30. (*f)();
  31. }
  32. };
  33.  
  34.  
  35. template <typename T>
  36. void assign_lambda(T&& f)
  37. {
  38. static RAIIFunctor<T> func;
  39.  
  40. func.assign(std::forward<T>(f));
  41. func();
  42. }
  43.  
  44. #include <iostream>
  45. #include <memory>
  46. struct S {
  47. int i_;
  48. S(int i) : i_{i} {}
  49. ~S() { std::cout << "~S " << i_ << std::endl; }
  50. };
  51.  
  52. int main() {
  53. S s(1);
  54. auto ptr = std::make_shared<S>(2);
  55. assign_lambda([ptr](){ std::cout << "lambda\n";} );
  56. std::cout << "end main\n";
  57. }
Success #stdin #stdout 0s 2988KB
stdin
Standard input is empty
stdout
lambda
end main
~S 1
~S 2