1 // DR 339 2 // 3 // Test of the use of member functions with SFINAE 4 typedef char yes_type; 5 struct no_type { char data[2]; }; 6 7 template<typename T> T create_a(); 8 9 template<bool, typename T = void> struct enable_if { typedef T type; }; 10 template<typename T> struct enable_if<false, T> { }; 11 12 template<typename T> 13 typename enable_if<(sizeof(create_a<T>().foo(), 1) > 0), 14 yes_type>::type 15 check_has_member_foo(const volatile T&); 16 17 no_type check_has_member_foo(...); 18 19 template<typename T> 20 struct has_foo 21 { 22 static const bool value = 23 (sizeof(check_has_member_foo(create_a<T const&>())) == sizeof(yes_type)); 24 }; 25 26 struct X { }; 27 struct Y { 28 void foo(); 29 }; 30 struct Z { 31 void foo(int); 32 }; 33 34 struct A { 35 int foo; 36 }; 37 38 struct B { 39 static int foo(); 40 }; 41 42 int a1[has_foo<X>::value? -1 : 1]; 43 int a2[has_foo<Y>::value? 1 : -1]; 44 int a3[has_foo<Z>::value? -1 : 1]; 45 int a4[has_foo<int>::value? -1 : 1]; 46 int a5[has_foo<A>::value? -1 : 1]; 47 int a6[has_foo<B>::value? 1 : -1]; 48