fork download
  1. #include <iostream>
  2.  
  3. template <bool FunctionWasInParameters> struct FunctionMarker {
  4. operator bool() const { return FunctionWasInParameters; }
  5.  
  6. operator int() const { return FunctionWasInParameters; }
  7. };
  8.  
  9. template <bool... values> struct Or;
  10.  
  11. template <bool first, bool... values> struct Or<first, values...> {
  12. static constexpr bool value = first || Or<values...>::value;
  13. };
  14.  
  15. template <> struct Or<> { static constexpr bool value = false; };
  16.  
  17. template <class T> struct is_FunctionMarker {
  18. static constexpr bool value = false;
  19. };
  20.  
  21. template <bool B> struct is_FunctionMarker<FunctionMarker<B>> {
  22. static constexpr bool value = true;
  23. };
  24.  
  25. #define OVERLOAD_OPERATOR_FOR_FUNCTION_MARKER(OPERATOR) \
  26.   template <bool B, class T> \
  27.   FunctionMarker<B> operator OPERATOR(FunctionMarker<B>, T) { \
  28.   return {}; \
  29.   } \
  30.   template <bool B, class T> \
  31.   FunctionMarker<B> operator OPERATOR(T, FunctionMarker<B>) { \
  32.   return {}; \
  33.   } \
  34.   /* to break ambiguity by specialization */ \
  35.   template <bool B, bool B2> \
  36.   FunctionMarker<B || B2> operator OPERATOR(FunctionMarker<B>, \
  37.   FunctionMarker<B2>) { \
  38.   return {}; \
  39.   }
  40.  
  41. OVERLOAD_OPERATOR_FOR_FUNCTION_MARKER(|| )
  42. OVERLOAD_OPERATOR_FOR_FUNCTION_MARKER(+)
  43. OVERLOAD_OPERATOR_FOR_FUNCTION_MARKER(*)
  44. // TODO: overload all other operators!
  45.  
  46. template <class... Args>
  47. auto function(Args... args)
  48. -> FunctionMarker<Or<is_FunctionMarker<Args>::value...>::value> {
  49. return {};
  50. }
  51.  
  52. FunctionMarker<false> function() { return {}; }
  53.  
  54. int main() {
  55. int a = function();
  56. int b = function(0);
  57. int c = function(function(0));
  58. int d = function(3 * function(1) + 2);
  59. bool e = function(true || function(1));
  60.  
  61. // clang-format off
  62. std::cout << a << "//a==false\n"
  63. << b << "//b==false\n"
  64. << c << "//c==true\n"
  65. << d << "//d==true (weakly-typed language)\n"
  66. << e << "//e==true (strongly-typed language)\n";
  67. }
  68.  
Success #stdin #stdout 0s 3140KB
stdin
Standard input is empty
stdout
0//a==false
0//b==false
1//c==true
1//d==true (weakly-typed language)
1//e==true (strongly-typed language)