This code fails to compile in most compilers but at first I intuitively expected SFINAE to protect me:
typedef void (*A)();
template < typename T >
st
SFINAE won't protect you there, the error happens after type deduction. However, this should work:
template < typename T, typename Type = typename T::type >
struct a_metafun { typedef Type type; };
By accesing T::type in a default template parameter we cause this to happen at substitution time, and at that time SFINAE kicks in.
Edit: After thinking some more, I'm not exactly sure why your current implementation fails. I think is because a_metafun has a member type type, one that causes a compilation error; it would be different if a_metafun didn't have a member type type at all.