fork download
  1. #include <iostream>
  2. #include <utility>
  3. #include <memory>
  4.  
  5. template<class Sig>class func;
  6. namespace details{
  7. template<class Sig>struct inner;
  8. template<class R,class...Args>
  9. struct inner<R(Args...)>{
  10. virtual ~inner() {};
  11. virtual R invoke(Args&&...args) =0;
  12. };
  13. template<class F,class Sig>struct impl;
  14. template<class F,class R,class...Args>
  15. struct impl<F,R(Args...)>:inner<R(Args...)>{
  16. F f;
  17. template<class... Ts>
  18. impl(Ts&&...ts):f(std::forward<Ts>(ts)...){}
  19. R invoke(Args&&...args)override{
  20. return f(std::forward<Args>(args)...);
  21. }
  22. };
  23. }
  24. template<class T>struct emplace_as{};
  25. template<class R,class...Args>
  26. class func<R(Args...)>{
  27. std::unique_ptr<details::inner<R(Args...)>> pImpl;
  28. public:
  29. R operator()(Args...args){
  30. return pImpl->invoke(std::forward<Args>(args)...);
  31. }
  32. explicit operator bool()const{return pImpl;}
  33. func(func&&)=default;
  34. template<class F,class...Ts,class=typename std::enable_if<
  35. std::is_convertible<decltype(std::declval<F>()(std::declval<Args>()...)),R>::value
  36. >::type>
  37. func(emplace_as<F>,Ts&&...ts):
  38. pImpl( new details::impl<F, R(Args...)>{std::forward<Ts>(ts)...} )
  39. {}
  40.  
  41. template<class F,class=typename std::enable_if<
  42. std::is_convertible<decltype(std::declval<F>()(std::declval<Args>()...)),R>::value
  43. >::type>
  44. func(F&&f):
  45. func(
  46. emplace_as<typename std::decay<F>::type>(),
  47. std::forward<F>(f)
  48. )
  49. {}
  50. };
  51.  
  52. int main() {
  53. func<void()> test = [](){ std::cout << "hello world\n"; };
  54. test();
  55. }
Success #stdin #stdout 0s 3428KB
stdin
Standard input is empty
stdout
hello world