#define INDIRECT_ENABLE_IF 1 #define USE_WRAP 1 #define USE_CHAR 1 #define SPECIALIZE_TRUE 1 #define SPECIALIZE_FALSE 1 #define USE_BOOST_ENABLE_IF 1 #define ALLOW_OK 0 #define ALLOW_SFINAE 1 struct false_type { static const bool value = false; }; struct true_type { static const bool value = true; }; #if USE_BOOST_ENABLE_IF #include using boost::enable_if; #elif INDIRECT_ENABLE_IF template struct enable_if_c { #if !SPECIALIZE_FALSE typedef T type; #endif }; #if SPECIALIZE_FALSE template struct enable_if_c { }; #endif #if SPECIALIZE_TRUE template struct enable_if_c { typedef T type; }; #endif template struct enable_if : enable_if_c<(Cond::value), T> {}; #else template struct enable_if { #if !SPECIALIZE_FALSE typedef T type; #endif }; #if SPECIALIZE_FALSE template struct enable_if {}; #endif #if SPECIALIZE_TRUE template struct enable_if { typedef T type; }; #endif #endif template struct is_int { typedef false_type type; }; template<> struct is_int { typedef true_type type; }; template struct is_not_int { typedef true_type type; }; template<> struct is_not_int { typedef false_type type; }; template struct wrap { typedef T2 type; }; template struct s { typename T::value x; }; template<> struct s { s(int) {} operator int() { return 0; } }; #if ALLOW_OK ^ USE_CHAR template #if USE_WRAP typename wrap< #endif typename enable_if< typename is_int::type #if USE_WRAP >::type #endif , s >::type f(T t) { return t; } #endif #if ALLOW_SFINAE ^ USE_CHAR template #if USE_WRAP typename wrap< #endif typename enable_if< typename is_not_int::type #if USE_WRAP >::type #endif , s >::type f(T t) { return t; } #endif #include int main() { #if USE_CHAR char x = 'a'; #else int x = 1; #endif std::cout << typeid(f(x)).name() << std::endl; int i = f(x); }