fork(4) download
  1. #include <iostream>
  2. #include <type_traits>
  3. #include <typeinfo>
  4.  
  5. using namespace std;
  6.  
  7. #define FOO(FUNCTION, DEFINE) template <typename T, typename S = decltype(declval<T>().FUNCTION)> static true_type __ ## DEFINE(int); \
  8.   template <typename T> static false_type __ ## DEFINE(...); \
  9.   template <typename T> using DEFINE = decltype(__ ## DEFINE<T>(0));
  10. #define BAR(CLASS, FUNCTION) [] {struct { \
  11.   template<typename R, typename S = decltype(declval<R>().FUNCTION)> static true_type Test(R*); \
  12.   template<typename R> static false_type Test(...); \
  13.   operator bool() const { return decltype(Test<CLASS>(0))::value; } } result; \
  14.   return result; }()
  15.  
  16. namespace details {
  17. FOO(test(declval<int>()), test_int)
  18. FOO(test(), test_void)
  19. }
  20.  
  21. struct a {
  22. void test();
  23. void test(int);
  24. };
  25.  
  26. struct b {
  27. int test(double);
  28. };
  29.  
  30. struct c {
  31. void test();
  32. };
  33.  
  34. template <typename T> enable_if_t<details::test_int<T>::value, void> outputInt() { cout << typeid(T).name() << " yes\n"; }
  35. template <typename T> enable_if_t<!details::test_int<T>::value, void> outputInt() { cout << typeid(T).name() << " no\n"; }
  36. template <typename T> enable_if_t<details::test_void<T>::value, void> outputVoid() { cout << typeid(T).name() << " yes\n"; }
  37. template <typename T> enable_if_t<!details::test_void<T>::value, void> outputVoid() { cout << typeid(T).name() << " no\n"; }
  38.  
  39. int main() {
  40. outputInt<a>();
  41. outputVoid<a>();
  42. outputInt<b>();
  43. outputVoid<b>();
  44. outputInt<c>();
  45. outputVoid<c>();
  46.  
  47.  
  48. if(BAR(a, test(declval<int>()))) cout << "a yes\n";
  49. if(BAR(a, test())) cout << "a yes\n";
  50. if(BAR(b, test(declval<int>()))) cout << "b yes\n";
  51. if(BAR(b, test())) cout << "b yes\n";
  52. if(BAR(c, test(declval<int>()))) cout << "c yes\n";
  53. if(BAR(c, test())) cout << "c yes\n";
  54. }
Compilation error #stdin compilation error #stdout 0s 3460KB
stdin
Standard input is empty
compilation info
prog.cpp: In lambda function:
prog.cpp:11:5: error: invalid declaration of member template in local class
     template<typename R, typename S = decltype(declval<R>().FUNCTION)> static true_type Test(R*); \
     ^
prog.cpp:48:8: note: in expansion of macro 'BAR'
     if(BAR(a, test(declval<int>()))) cout << "a yes\n";
        ^
prog.cpp:12:5: error: invalid declaration of member template in local class
     template<typename R> static false_type Test(...); \
     ^
prog.cpp:48:8: note: in expansion of macro 'BAR'
     if(BAR(a, test(declval<int>()))) cout << "a yes\n";
        ^
prog.cpp: In member function 'main()::<lambda()>::<anonymous struct>::operator bool() const':
prog.cpp:13:45: error: 'Test' was not declared in this scope
     operator bool() const { return decltype(Test<CLASS>(0))::value; } } result; \
                                             ^
prog.cpp:48:8: note: in expansion of macro 'BAR'
     if(BAR(a, test(declval<int>()))) cout << "a yes\n";
        ^
prog.cpp:13:36: error: decltype evaluates to '<type error>', which is not a class or enumeration type
     operator bool() const { return decltype(Test<CLASS>(0))::value; } } result; \
                                    ^
prog.cpp:48:8: note: in expansion of macro 'BAR'
     if(BAR(a, test(declval<int>()))) cout << "a yes\n";
        ^
prog.cpp: In lambda function:
prog.cpp:11:5: error: invalid declaration of member template in local class
     template<typename R, typename S = decltype(declval<R>().FUNCTION)> static true_type Test(R*); \
     ^
prog.cpp:49:8: note: in expansion of macro 'BAR'
     if(BAR(a, test())) cout << "a yes\n";
        ^
prog.cpp:12:5: error: invalid declaration of member template in local class
     template<typename R> static false_type Test(...); \
     ^
prog.cpp:49:8: note: in expansion of macro 'BAR'
     if(BAR(a, test())) cout << "a yes\n";
        ^
prog.cpp: In member function 'main()::<lambda()>::<anonymous struct>::operator bool() const':
prog.cpp:13:45: error: 'Test' was not declared in this scope
     operator bool() const { return decltype(Test<CLASS>(0))::value; } } result; \
                                             ^
prog.cpp:49:8: note: in expansion of macro 'BAR'
     if(BAR(a, test())) cout << "a yes\n";
        ^
prog.cpp:13:36: error: decltype evaluates to '<type error>', which is not a class or enumeration type
     operator bool() const { return decltype(Test<CLASS>(0))::value; } } result; \
                                    ^
prog.cpp:49:8: note: in expansion of macro 'BAR'
     if(BAR(a, test())) cout << "a yes\n";
        ^
prog.cpp: In lambda function:
prog.cpp:11:5: error: invalid declaration of member template in local class
     template<typename R, typename S = decltype(declval<R>().FUNCTION)> static true_type Test(R*); \
     ^
prog.cpp:50:8: note: in expansion of macro 'BAR'
     if(BAR(b, test(declval<int>()))) cout << "b yes\n";
        ^
prog.cpp:12:5: error: invalid declaration of member template in local class
     template<typename R> static false_type Test(...); \
     ^
prog.cpp:50:8: note: in expansion of macro 'BAR'
     if(BAR(b, test(declval<int>()))) cout << "b yes\n";
        ^
prog.cpp: In member function 'main()::<lambda()>::<anonymous struct>::operator bool() const':
prog.cpp:13:45: error: 'Test' was not declared in this scope
     operator bool() const { return decltype(Test<CLASS>(0))::value; } } result; \
                                             ^
prog.cpp:50:8: note: in expansion of macro 'BAR'
     if(BAR(b, test(declval<int>()))) cout << "b yes\n";
        ^
prog.cpp:13:36: error: decltype evaluates to '<type error>', which is not a class or enumeration type
     operator bool() const { return decltype(Test<CLASS>(0))::value; } } result; \
                                    ^
prog.cpp:50:8: note: in expansion of macro 'BAR'
     if(BAR(b, test(declval<int>()))) cout << "b yes\n";
        ^
prog.cpp: In lambda function:
prog.cpp:11:5: error: invalid declaration of member template in local class
     template<typename R, typename S = decltype(declval<R>().FUNCTION)> static true_type Test(R*); \
     ^
prog.cpp:51:8: note: in expansion of macro 'BAR'
     if(BAR(b, test())) cout << "b yes\n";
        ^
prog.cpp:12:5: error: invalid declaration of member template in local class
     template<typename R> static false_type Test(...); \
     ^
prog.cpp:51:8: note: in expansion of macro 'BAR'
     if(BAR(b, test())) cout << "b yes\n";
        ^
prog.cpp: In member function 'main()::<lambda()>::<anonymous struct>::operator bool() const':
prog.cpp:13:45: error: 'Test' was not declared in this scope
     operator bool() const { return decltype(Test<CLASS>(0))::value; } } result; \
                                             ^
prog.cpp:51:8: note: in expansion of macro 'BAR'
     if(BAR(b, test())) cout << "b yes\n";
        ^
prog.cpp:13:36: error: decltype evaluates to '<type error>', which is not a class or enumeration type
     operator bool() const { return decltype(Test<CLASS>(0))::value; } } result; \
                                    ^
prog.cpp:51:8: note: in expansion of macro 'BAR'
     if(BAR(b, test())) cout << "b yes\n";
        ^
prog.cpp: In lambda function:
prog.cpp:11:5: error: invalid declaration of member template in local class
     template<typename R, typename S = decltype(declval<R>().FUNCTION)> static true_type Test(R*); \
     ^
prog.cpp:52:8: note: in expansion of macro 'BAR'
     if(BAR(c, test(declval<int>()))) cout << "c yes\n";
        ^
prog.cpp:12:5: error: invalid declaration of member template in local class
     template<typename R> static false_type Test(...); \
     ^
prog.cpp:52:8: note: in expansion of macro 'BAR'
     if(BAR(c, test(declval<int>()))) cout << "c yes\n";
        ^
prog.cpp: In member function 'main()::<lambda()>::<anonymous struct>::operator bool() const':
prog.cpp:13:45: error: 'Test' was not declared in this scope
     operator bool() const { return decltype(Test<CLASS>(0))::value; } } result; \
                                             ^
prog.cpp:52:8: note: in expansion of macro 'BAR'
     if(BAR(c, test(declval<int>()))) cout << "c yes\n";
        ^
prog.cpp:13:36: error: decltype evaluates to '<type error>', which is not a class or enumeration type
     operator bool() const { return decltype(Test<CLASS>(0))::value; } } result; \
                                    ^
prog.cpp:52:8: note: in expansion of macro 'BAR'
     if(BAR(c, test(declval<int>()))) cout << "c yes\n";
        ^
prog.cpp: In lambda function:
prog.cpp:11:5: error: invalid declaration of member template in local class
     template<typename R, typename S = decltype(declval<R>().FUNCTION)> static true_type Test(R*); \
     ^
prog.cpp:53:8: note: in expansion of macro 'BAR'
     if(BAR(c, test())) cout << "c yes\n";
        ^
prog.cpp:12:5: error: invalid declaration of member template in local class
     template<typename R> static false_type Test(...); \
     ^
prog.cpp:53:8: note: in expansion of macro 'BAR'
     if(BAR(c, test())) cout << "c yes\n";
        ^
prog.cpp: In member function 'main()::<lambda()>::<anonymous struct>::operator bool() const':
prog.cpp:13:45: error: 'Test' was not declared in this scope
     operator bool() const { return decltype(Test<CLASS>(0))::value; } } result; \
                                             ^
prog.cpp:53:8: note: in expansion of macro 'BAR'
     if(BAR(c, test())) cout << "c yes\n";
        ^
prog.cpp:13:36: error: decltype evaluates to '<type error>', which is not a class or enumeration type
     operator bool() const { return decltype(Test<CLASS>(0))::value; } } result; \
                                    ^
prog.cpp:53:8: note: in expansion of macro 'BAR'
     if(BAR(c, test())) cout << "c yes\n";
        ^
stdout
Standard output is empty