I was surprised to find that the following code doesn't compile with boost 1.55, where boost::result_of is itself sfinae friendly. template < typename T > typename boost::lazy_enable_if_c< boost::is_class<T>::value, boost::result_of<T(int)>
::type test(int){}
template < typename > void test(...) {} struct A{}; // boost::result_of<A(int)> is a valid type that doesn't have a member called "type" int main(int argc, const char * argv[]) { test<A>(0); // test<A>(int) meant to be a substitution failure return 0; } For example, on clang++-3.4 with -std=c++11, I got: clang++-mp-3.4 -std=c++11 -I /opt/local/include/ main.cpp In file included from main.cpp:1: In file included from /opt/local/include/boost/type_traits.hpp:65: In file included from /opt/local/include/boost/type_traits/is_nothrow_move_assignable.hpp:22: /opt/local/include/boost/utility/enable_if.hpp:40:25: error: no type named 'type' in 'boost::result_of<A (int)>' typedef typename T::type type; ~~~~~~~~~~~~^~~~ main.cpp:12:1: note: in instantiation of template class 'boost::lazy_enable_if_c<true, boost::result_of<A (int)> >' requested here typename boost::lazy_enable_if_c< ^ main.cpp:16:1: note: while substituting explicitly-specified template arguments into function template 'test' test(int){} ^ 1 error generated. But if lazy_enable_if_c had been implemented as template <bool B, class T> struct lazy_enable_if_c : T {}; // inherits from T template <class T> struct lazy_enable_if_c<false, T> {}; The above test code would compile fine. However, the current implementation template <bool B, class T> struct lazy_enable_if_c { typedef typename T::type type; // this is what caused the compile error }; template <class T> struct lazy_enable_if_c<false, T> {}; seems to evaluate T::type too soon, and results in a compile error rather than a substitution failure. I wonder if the current implementation is chosen deliberately to disallow use cases like the test code? But I imagine allowing lazy_enable_if etc to be (more) sfinae friendly could be very useful. I was able to find a workaround for the test code: template < typename T > typename boost::enable_if_c< boost::is_class<T>::value, boost::result_of<T(int)>
::type::type // when T = A, this is a substitution failure test(int){}
Hui