fork download
  1. #include <iostream>
  2. #include <future>
  3. #include <functional>
  4. #include <type_traits>
  5.  
  6. namespace std
  7. {
  8. template<class T>
  9. static constexpr bool is_member_pointer_v = std::is_member_pointer<T>::value;
  10. template<class T>
  11. static constexpr bool is_function_v = std::is_function<T>::value;
  12. template<class B, class T>
  13. static constexpr bool is_base_of_v = std::is_base_of<B, T>::value;
  14. namespace detail {
  15. template <class T>
  16. struct is_reference_wrapper : std::false_type {};
  17. template <class U>
  18. struct is_reference_wrapper<std::reference_wrapper<U>> : std::true_type {};
  19. template <class T>
  20. constexpr bool is_reference_wrapper_v = is_reference_wrapper<T>::value;
  21.  
  22. template <class Base, class T, class Derived, class... Args>
  23. auto INVOKE(T Base::*pmf, Derived&& ref, Args&&... args)
  24. noexcept(noexcept((std::forward<Derived>(ref).*pmf)(std::forward<Args>(args)...)))
  25. -> std::enable_if_t<std::is_function_v<T> &&
  26. std::is_base_of_v<Base, std::decay_t<Derived>>,
  27. decltype((std::forward<Derived>(ref).*pmf)(std::forward<Args>(args)...))>
  28. {
  29. return (std::forward<Derived>(ref).*pmf)(std::forward<Args>(args)...);
  30. }
  31.  
  32. template <class Base, class T, class RefWrap, class... Args>
  33. auto INVOKE(T Base::*pmf, RefWrap&& ref, Args&&... args)
  34. noexcept(noexcept((ref.get().*pmf)(std::forward<Args>(args)...)))
  35. -> std::enable_if_t<std::is_function_v<T> &&
  36. is_reference_wrapper_v<std::decay_t<RefWrap>>,
  37. decltype((ref.get().*pmf)(std::forward<Args>(args)...))>
  38.  
  39. {
  40. return (ref.get().*pmf)(std::forward<Args>(args)...);
  41. }
  42.  
  43. template <class Base, class T, class Pointer, class... Args>
  44. auto INVOKE(T Base::*pmf, Pointer&& ptr, Args&&... args)
  45. noexcept(noexcept(((*std::forward<Pointer>(ptr)).*pmf)(std::forward<Args>(args)...)))
  46. -> std::enable_if_t<std::is_function_v<T> &&
  47. !is_reference_wrapper_v<std::decay_t<Pointer>> &&
  48. !std::is_base_of_v<Base, std::decay_t<Pointer>>,
  49. decltype(((*std::forward<Pointer>(ptr)).*pmf)(std::forward<Args>(args)...))>
  50. {
  51. return ((*std::forward<Pointer>(ptr)).*pmf)(std::forward<Args>(args)...);
  52. }
  53.  
  54. template <class Base, class T, class Derived>
  55. auto INVOKE(T Base::*pmd, Derived&& ref)
  56. noexcept(noexcept(std::forward<Derived>(ref).*pmd))
  57. -> std::enable_if_t<!std::is_function_v<T> &&
  58. std::is_base_of_v<Base, std::decay_t<Derived>>,
  59. decltype(std::forward<Derived>(ref).*pmd)>
  60. {
  61. return std::forward<Derived>(ref).*pmd;
  62. }
  63.  
  64. template <class Base, class T, class RefWrap>
  65. auto INVOKE(T Base::*pmd, RefWrap&& ref)
  66. noexcept(noexcept(ref.get().*pmd))
  67. -> std::enable_if_t<!std::is_function_v<T> &&
  68. is_reference_wrapper_v<std::decay_t<RefWrap>>,
  69. decltype(ref.get().*pmd)>
  70. {
  71. return ref.get().*pmd;
  72. }
  73.  
  74. template <class Base, class T, class Pointer>
  75. auto INVOKE(T Base::*pmd, Pointer&& ptr)
  76. noexcept(noexcept((*std::forward<Pointer>(ptr)).*pmd))
  77. -> std::enable_if_t<!std::is_function_v<T> &&
  78. !is_reference_wrapper_v<std::decay_t<Pointer>> &&
  79. !std::is_base_of_v<Base, std::decay_t<Pointer>>,
  80. decltype((*std::forward<Pointer>(ptr)).*pmd)>
  81. {
  82. return (*std::forward<Pointer>(ptr)).*pmd;
  83. }
  84.  
  85. template <class F, class... Args>
  86. auto INVOKE(F&& f, Args&&... args)
  87. noexcept(noexcept(std::forward<F>(f)(std::forward<Args>(args)...)))
  88. -> std::enable_if_t<!std::is_member_pointer_v<std::decay_t<F>>,
  89. decltype(std::forward<F>(f)(std::forward<Args>(args)...))>
  90. {
  91. return std::forward<F>(f)(std::forward<Args>(args)...);
  92. }
  93. } // namespace detail
  94.  
  95. template< class F, class... ArgTypes >
  96. auto invoke(F&& f, ArgTypes&&... args)
  97. // exception specification for QoI
  98. noexcept(noexcept(detail::INVOKE(std::forward<F>(f), std::forward<ArgTypes>(args)...)))
  99. -> decltype(detail::INVOKE(std::forward<F>(f), std::forward<ArgTypes>(args)...))
  100. {
  101. return detail::INVOKE(std::forward<F>(f), std::forward<ArgTypes>(args)...);
  102. }
  103. }
  104.  
  105. template<class Fn, class... Args>
  106. inline auto runAsyncTerminateOnException(Fn&& fn, Args&&... args) {
  107.  
  108. return std::async(std::launch::async, [=]() -> decltype(auto) {
  109. try {
  110. return std::invoke(fn, args...);
  111. } catch (...) {
  112. std::cout << "Terminate Called!" << std::endl;
  113. std::terminate();
  114. }
  115. });
  116. }
  117.  
  118. struct Foo {
  119. template<class... Args>
  120. void print(Args&&... args) {
  121. printf("Foo::print(%d)\n", std::forward<Args>(args)...);
  122. }
  123. };
  124.  
  125. int main() {
  126. Foo foo;
  127. std::future<void> future = runAsyncTerminateOnException(&Foo::print<int>, &foo, 2);
  128. // your code goes here
  129. return 0;
  130. }
Compilation error #stdin compilation error #stdout 0s 8600KB
stdin
Standard input is empty
compilation info
prog.cpp: In instantiation of 'runAsyncTerminateOnException(Fn&&, Args&& ...)::<lambda()> [with Fn = void (Foo::*)(int&&); Args = {Foo*, int}]':
prog.cpp:110:36:   required from 'struct runAsyncTerminateOnException(Fn&&, Args&& ...) [with Fn = void (Foo::*)(int&&); Args = {Foo*, int}]::<lambda()>'
prog.cpp:108:22:   required from 'auto runAsyncTerminateOnException(Fn&&, Args&& ...) [with Fn = void (Foo::*)(int&&); Args = {Foo*, int}]'
prog.cpp:127:86:   required from here
prog.cpp:110:31: error: no matching function for call to 'invoke(void (Foo::* const&)(int&&), Foo* const&, const int&)'
             return std::invoke(fn, args...);
                               ^
prog.cpp:96:6: note: candidate: template<class F, class ... ArgTypes> decltype (std::detail::INVOKE(forward<F>(f), (forward<ArgTypes>)(std::invoke::args)...)) std::invoke(F&&, ArgTypes&& ...)
 auto invoke(F&& f, ArgTypes&&... args)
      ^
prog.cpp:96:6: note:   template argument deduction/substitution failed:
prog.cpp: In substitution of 'template<class F, class ... ArgTypes> decltype (std::detail::INVOKE(forward<F>(f), (forward<ArgTypes>)(std::invoke::args)...)) std::invoke(F&&, ArgTypes&& ...) [with F = void (Foo::* const&)(int&&); ArgTypes = {Foo* const&, const int&}]':
prog.cpp:110:31:   required from 'runAsyncTerminateOnException(Fn&&, Args&& ...)::<lambda()> [with Fn = void (Foo::*)(int&&); Args = {Foo*, int}]'
prog.cpp:110:36:   required from 'struct runAsyncTerminateOnException(Fn&&, Args&& ...) [with Fn = void (Foo::*)(int&&); Args = {Foo*, int}]::<lambda()>'
prog.cpp:108:22:   required from 'auto runAsyncTerminateOnException(Fn&&, Args&& ...) [with Fn = void (Foo::*)(int&&); Args = {Foo*, int}]'
prog.cpp:127:86:   required from here
prog.cpp:99:28: error: no matching function for call to 'INVOKE(void (Foo::* const&)(int&&), Foo* const&, const int&)'
  -> decltype(detail::INVOKE(std::forward<F>(f), std::forward<ArgTypes>(args)...))
                            ^
prog.cpp:23:6: note: candidate: template<class Base, class T, class Derived, class ... Args> std::enable_if_t<(std::is_function_v<T> && std::is_base_of_v<Base, typename std::decay<Derived>::type>), decltype ((forward<Derived>)(*std::detail::INVOKE::ref).*std::detail::INVOKE::pmf((forward<Args>)(std::detail::INVOKE::args)...))> std::detail::INVOKE(T Base::*, Derived&&, Args&& ...)
 auto INVOKE(T Base::*pmf, Derived&& ref, Args&&... args)
      ^
prog.cpp:23:6: note:   template argument deduction/substitution failed:
prog.cpp: In substitution of 'template<class Base, class T, class Derived, class ... Args> std::enable_if_t<(std::is_function_v<T> && std::is_base_of_v<Base, typename std::decay<Derived>::type>), decltype ((forward<Derived>)(*std::detail::INVOKE::ref).*std::detail::INVOKE::pmf((forward<Args>)(std::detail::INVOKE::args)...))> std::detail::INVOKE(T Base::*, Derived&&, Args&& ...) [with Base = Foo; T = void(int&&); Derived = Foo* const&; Args = {const int&}]':
prog.cpp:99:28:   required by substitution of 'template<class F, class ... ArgTypes> decltype (std::detail::INVOKE(forward<F>(f), (forward<ArgTypes>)(std::invoke::args)...)) std::invoke(F&&, ArgTypes&& ...) [with F = void (Foo::* const&)(int&&); ArgTypes = {Foo* const&, const int&}]'
prog.cpp:110:31:   required from 'runAsyncTerminateOnException(Fn&&, Args&& ...)::<lambda()> [with Fn = void (Foo::*)(int&&); Args = {Foo*, int}]'
prog.cpp:110:36:   required from 'struct runAsyncTerminateOnException(Fn&&, Args&& ...) [with Fn = void (Foo::*)(int&&); Args = {Foo*, int}]::<lambda()>'
prog.cpp:108:22:   required from 'auto runAsyncTerminateOnException(Fn&&, Args&& ...) [with Fn = void (Foo::*)(int&&); Args = {Foo*, int}]'
prog.cpp:127:86:   required from here
prog.cpp:27:41: error: cannot apply member pointer 'pmf' to 'std::forward<Foo* const&>((* & ref))', which is of non-class type 'Foo*'
     decltype((std::forward<Derived>(ref).*pmf)(std::forward<Args>(args)...))>
                                         ^
prog.cpp: In substitution of 'template<class F, class ... ArgTypes> decltype (std::detail::INVOKE(forward<F>(f), (forward<ArgTypes>)(std::invoke::args)...)) std::invoke(F&&, ArgTypes&& ...) [with F = void (Foo::* const&)(int&&); ArgTypes = {Foo* const&, const int&}]':
prog.cpp:110:31:   required from 'runAsyncTerminateOnException(Fn&&, Args&& ...)::<lambda()> [with Fn = void (Foo::*)(int&&); Args = {Foo*, int}]'
prog.cpp:110:36:   required from 'struct runAsyncTerminateOnException(Fn&&, Args&& ...) [with Fn = void (Foo::*)(int&&); Args = {Foo*, int}]::<lambda()>'
prog.cpp:108:22:   required from 'auto runAsyncTerminateOnException(Fn&&, Args&& ...) [with Fn = void (Foo::*)(int&&); Args = {Foo*, int}]'
prog.cpp:127:86:   required from here
prog.cpp:33:6: note: candidate: template<class Base, class T, class RefWrap, class ... Args> std::enable_if_t<(std::is_function_v<T> && std::detail::is_reference_wrapper_v<typename std::decay<Derived>::type>), decltype (std::detail::INVOKE::ref->get().*std::detail::INVOKE::pmf((forward<Args>)(std::detail::INVOKE::args)...))> std::detail::INVOKE(T Base::*, RefWrap&&, Args&& ...)
 auto INVOKE(T Base::*pmf, RefWrap&& ref, Args&&... args)
      ^
prog.cpp:33:6: note:   template argument deduction/substitution failed:
prog.cpp: In substitution of 'template<class Base, class T, class RefWrap, class ... Args> std::enable_if_t<(std::is_function_v<T> && std::detail::is_reference_wrapper_v<typename std::decay<Derived>::type>), decltype (std::detail::INVOKE::ref->get().*std::detail::INVOKE::pmf((forward<Args>)(std::detail::INVOKE::args)...))> std::detail::INVOKE(T Base::*, RefWrap&&, Args&& ...) [with Base = Foo; T = void(int&&); RefWrap = Foo* const&; Args = {const int&}]':
prog.cpp:99:28:   required by substitution of 'template<class F, class ... ArgTypes> decltype (std::detail::INVOKE(forward<F>(f), (forward<ArgTypes>)(std::invoke::args)...)) std::invoke(F&&, ArgTypes&& ...) [with F = void (Foo::* const&)(int&&); ArgTypes = {Foo* const&, const int&}]'
prog.cpp:110:31:   required from 'runAsyncTerminateOnException(Fn&&, Args&& ...)::<lambda()> [with Fn = void (Foo::*)(int&&); Args = {Foo*, int}]'
prog.cpp:110:36:   required from 'struct runAsyncTerminateOnException(Fn&&, Args&& ...) [with Fn = void (Foo::*)(int&&); Args = {Foo*, int}]::<lambda()>'
prog.cpp:108:22:   required from 'auto runAsyncTerminateOnException(Fn&&, Args&& ...) [with Fn = void (Foo::*)(int&&); Args = {Foo*, int}]'
prog.cpp:127:86:   required from here
prog.cpp:37:24: error: request for member 'get' in 'ref', which is of pointer type 'Foo* const' (maybe you meant to use '->' ?)
     decltype((ref.get().*pmf)(std::forward<Args>(args)...))>
                        ^
prog.cpp: In substitution of 'template<class F, class ... ArgTypes> decltype (std::detail::INVOKE(forward<F>(f), (forward<ArgTypes>)(std::invoke::args)...)) std::invoke(F&&, ArgTypes&& ...) [with F = void (Foo::* const&)(int&&); ArgTypes = {Foo* const&, const int&}]':
prog.cpp:110:31:   required from 'runAsyncTerminateOnException(Fn&&, Args&& ...)::<lambda()> [with Fn = void (Foo::*)(int&&); Args = {Foo*, int}]'
prog.cpp:110:36:   required from 'struct runAsyncTerminateOnException(Fn&&, Args&& ...) [with Fn = void (Foo::*)(int&&); Args = {Foo*, int}]::<lambda()>'
prog.cpp:108:22:   required from 'auto runAsyncTerminateOnException(Fn&&, Args&& ...) [with Fn = void (Foo::*)(int&&); Args = {Foo*, int}]'
prog.cpp:127:86:   required from here
prog.cpp:44:6: note: candidate: template<class Base, class T, class Pointer, class ... Args> std::enable_if_t<((std::is_function_v<T> && (! std::detail::is_reference_wrapper_v<typename std::decay<Derived>::type>)) && (! std::is_base_of_v<Base, typename std::decay<Derived>::type>)), decltype (*(forward<Pointer>)(*std::detail::INVOKE::ptr).*std::detail::INVOKE::pmf((forward<Args>)(std::detail::INVOKE::args)...))> std::detail::INVOKE(T Base::*, Pointer&&, Args&& ...)
 auto INVOKE(T Base::*pmf, Pointer&& ptr, Args&&... args)
      ^
prog.cpp:44:6: note:   template argument deduction/substitution failed:
prog.cpp: In substitution of 'template<class Base, class T, class Pointer, class ... Args> std::enable_if_t<((std::is_function_v<T> && (! std::detail::is_reference_wrapper_v<typename std::decay<Derived>::type>)) && (! std::is_base_of_v<Base, typename std::decay<Derived>::type>)), decltype (*(forward<Pointer>)(*std::detail::INVOKE::ptr).*std::detail::INVOKE::pmf((forward<Args>)(std::detail::INVOKE::args)...))> std::detail::INVOKE(T Base::*, Pointer&&, Args&& ...) [with Base = Foo; T = void(int&&); Pointer = Foo* const&; Args = {const int&}]':
prog.cpp:99:28:   required by substitution of 'template<class F, class ... ArgTypes> decltype (std::detail::INVOKE(forward<F>(f), (forward<ArgTypes>)(std::invoke::args)...)) std::invoke(F&&, ArgTypes&& ...) [with F = void (Foo::* const&)(int&&); ArgTypes = {Foo* const&, const int&}]'
prog.cpp:110:31:   required from 'runAsyncTerminateOnException(Fn&&, Args&& ...)::<lambda()> [with Fn = void (Foo::*)(int&&); Args = {Foo*, int}]'
prog.cpp:110:36:   required from 'struct runAsyncTerminateOnException(Fn&&, Args&& ...) [with Fn = void (Foo::*)(int&&); Args = {Foo*, int}]::<lambda()>'
prog.cpp:108:22:   required from 'auto runAsyncTerminateOnException(Fn&&, Args&& ...) [with Fn = void (Foo::*)(int&&); Args = {Foo*, int}]'
prog.cpp:127:86:   required from here
prog.cpp:49:50: error: cannot bind 'const int' lvalue to 'int&&'
     decltype(((*std::forward<Pointer>(ptr)).*pmf)(std::forward<Args>(args)...))>
                                                  ^
prog.cpp: In substitution of 'template<class F, class ... ArgTypes> decltype (std::detail::INVOKE(forward<F>(f), (forward<ArgTypes>)(std::invoke::args)...)) std::invoke(F&&, ArgTypes&& ...) [with F = void (Foo::* const&)(int&&); ArgTypes = {Foo* const&, const int&}]':
prog.cpp:110:31:   required from 'runAsyncTerminateOnException(Fn&&, Args&& ...)::<lambda()> [with Fn = void (Foo::*)(int&&); Args = {Foo*, int}]'
prog.cpp:110:36:   required from 'struct runAsyncTerminateOnException(Fn&&, Args&& ...) [with Fn = void (Foo::*)(int&&); Args = {Foo*, int}]::<lambda()>'
prog.cpp:108:22:   required from 'auto runAsyncTerminateOnException(Fn&&, Args&& ...) [with Fn = void (Foo::*)(int&&); Args = {Foo*, int}]'
prog.cpp:127:86:   required from here
prog.cpp:55:6: note: candidate: template<class Base, class T, class Derived> std::enable_if_t<((! std::is_function_v<T>) && std::is_base_of_v<Base, typename std::decay<Derived>::type>), decltype ((forward<Derived>)(*std::detail::INVOKE::ref).*std::detail::INVOKE::pmd)> std::detail::INVOKE(T Base::*, Derived&&)
 auto INVOKE(T Base::*pmd, Derived&& ref)
      ^
prog.cpp:55:6: note:   template argument deduction/substitution failed:
prog.cpp:99:28: note:   candidate expects 2 arguments, 3 provided
  -> decltype(detail::INVOKE(std::forward<F>(f), std::forward<ArgTypes>(args)...))
                            ^
prog.cpp:65:6: note: candidate: template<class Base, class T, class RefWrap> std::enable_if_t<((! std::is_function_v<T>) && std::detail::is_reference_wrapper_v<typename std::decay<Derived>::type>), decltype (std::detail::INVOKE::ref->get().*std::detail::INVOKE::pmd)> std::detail::INVOKE(T Base::*, RefWrap&&)
 auto INVOKE(T Base::*pmd, RefWrap&& ref)
      ^
prog.cpp:65:6: note:   template argument deduction/substitution failed:
prog.cpp:99:28: note:   candidate expects 2 arguments, 3 provided
  -> decltype(detail::INVOKE(std::forward<F>(f), std::forward<ArgTypes>(args)...))
                            ^
prog.cpp:75:6: note: candidate: template<class Base, class T, class Pointer> std::enable_if_t<(((! std::is_function_v<T>) && (! std::detail::is_reference_wrapper_v<typename std::decay<Derived>::type>)) && (! std::is_base_of_v<Base, typename std::decay<Derived>::type>)), decltype (*(forward<Pointer>)(*std::detail::INVOKE::ptr).*std::detail::INVOKE::pmd)> std::detail::INVOKE(T Base::*, Pointer&&)
 auto INVOKE(T Base::*pmd, Pointer&& ptr)
      ^
prog.cpp:75:6: note:   template argument deduction/substitution failed:
prog.cpp:99:28: note:   candidate expects 2 arguments, 3 provided
  -> decltype(detail::INVOKE(std::forward<F>(f), std::forward<ArgTypes>(args)...))
                            ^
prog.cpp:86:6: note: candidate: template<class F, class ... Args> std::enable_if_t<(! std::is_member_pointer_v<typename std::decay<_Tp>::type>), decltype (forward<F>(f)((forward<Args>)(std::detail::INVOKE::args)...))> std::detail::INVOKE(F&&, Args&& ...)
 auto INVOKE(F&& f, Args&&... args)
      ^
prog.cpp:86:6: note:   template argument deduction/substitution failed:
prog.cpp: In substitution of 'template<class F, class ... Args> std::enable_if_t<(! std::is_member_pointer_v<typename std::decay<_Tp>::type>), decltype (forward<F>(f)((forward<Args>)(std::detail::INVOKE::args)...))> std::detail::INVOKE(F&&, Args&& ...) [with F = void (Foo::* const&)(int&&); Args = {Foo* const&, const int&}]':
prog.cpp:99:28:   required by substitution of 'template<class F, class ... ArgTypes> decltype (std::detail::INVOKE(forward<F>(f), (forward<ArgTypes>)(std::invoke::args)...)) std::invoke(F&&, ArgTypes&& ...) [with F = void (Foo::* const&)(int&&); ArgTypes = {Foo* const&, const int&}]'
prog.cpp:110:31:   required from 'runAsyncTerminateOnException(Fn&&, Args&& ...)::<lambda()> [with Fn = void (Foo::*)(int&&); Args = {Foo*, int}]'
prog.cpp:110:36:   required from 'struct runAsyncTerminateOnException(Fn&&, Args&& ...) [with Fn = void (Foo::*)(int&&); Args = {Foo*, int}]::<lambda()>'
prog.cpp:108:22:   required from 'auto runAsyncTerminateOnException(Fn&&, Args&& ...) [with Fn = void (Foo::*)(int&&); Args = {Foo*, int}]'
prog.cpp:127:86:   required from here
prog.cpp:89:32: error: must use '.*' or '->*' to call pointer-to-member function in 'std::forward<void (Foo::* const&)(int&&)>((* & f)) (...)', e.g. '(... ->* std::forward<void (Foo::* const&)(int&&)>((* & f))) (...)'
     decltype(std::forward<F>(f)(std::forward<Args>(args)...))>
                                ^
In file included from prog.cpp:2:0:
/usr/include/c++/5/future:1703:5: error: 'std::future<typename std::result_of<_Functor(_ArgTypes ...)>::type> std::async(std::launch, _Fn&&, _Args&& ...) [with _Fn = runAsyncTerminateOnException(Fn&&, Args&& ...) [with Fn = void (Foo::*)(int&&); Args = {Foo*, int}]::<lambda()>; _Args = {}; typename std::result_of<_Functor(_ArgTypes ...)>::type = void]', declared using local type 'runAsyncTerminateOnException(Fn&&, Args&& ...) [with Fn = void (Foo::*)(int&&); Args = {Foo*, int}]::<lambda()>', is used but never defined [-fpermissive]
     async(launch __policy, _Fn&& __fn, _Args&&... __args)
     ^
stdout
Standard output is empty