fork(1) download
  1. #include <iostream>
  2. #include <type_traits>
  3.  
  4. template<typename T, typename = void>
  5. struct HasFoo: std::false_type
  6. {};
  7.  
  8. template<typename T>
  9. struct HasFoo<T, std::enable_if_t<std::is_same<decltype(std::declval<T>().foo()), void>::value>>: std::true_type
  10. {};
  11.  
  12. template<typename T>
  13. constexpr bool HasFoo_v = HasFoo<T>::value;
  14.  
  15. template<bool B, typename F>
  16. struct ConditioanlCall
  17. {
  18. ConditioanlCall(F function)
  19. {}
  20. };
  21.  
  22. template<typename F>
  23. struct ConditioanlCall<true, F>
  24. {
  25. ConditioanlCall(F function)
  26. {
  27. auto ignore = false;
  28. function(ignore);
  29. }
  30. };
  31. template<bool B, typename F>
  32. void callConditional(F&& function)
  33. {
  34. ConditioanlCall<B, F>{std::forward<F>(function)};
  35. }
  36.  
  37. #define CONSTEXPR_IF(condition, action) \
  38.   callConditional<condition>([&](auto) action);
  39.  
  40.  
  41. struct A
  42. {
  43. void foo()
  44. {
  45. std::cout << "From class foo!\n";
  46. }
  47. };
  48.  
  49. struct B {};
  50.  
  51. void foo(B)
  52. {
  53. std::cout << "From standalone foo!\n";
  54. }
  55. void foo(A)
  56. {
  57. std::cout << "From standalone foo!\n";
  58. }
  59.  
  60.  
  61. int main()
  62. {
  63. A a;
  64. B b;
  65. CONSTEXPR_IF(!HasFoo_v<B>, {foo(b);});
  66. CONSTEXPR_IF(HasFoo_v<A>, {a.foo();});
  67.  
  68. return 0;
  69. }
Success #stdin #stdout 0s 3468KB
stdin
Standard input is empty
stdout
From standalone foo!
From class foo!