This is not only a problem with enable_if. You get the same error in Visual Studio and gcc with the following code:
struct TypeVoid { typedef void type; }; template<typename T> void f(); template<typename T> typename T::type f() { } int main() { f<TypeVoid>(); return 0; }
I think the main problem is that the return type (before instantiation) is part of the signature of the template function. There is more details here .
As for your code, if the declaration is relevant to the definition, you should match both:
// Declaration template <typename T> typename boost::enable_if<boost::is_same<T, int> >::type foo(T t); // Definition template <typename T> typename boost::enable_if<boost::is_same<T, int> >::type foo(T t) { }
If the declaration refers to another function, the compiler can never choose the right one for ints, because both of them are valid. However, you can disable the first for int with disable_if:
// Other function declaration template <typename T> typename boost::disable_if<boost::is_same<T, int> >::type foo(T t); // Defition template <typename T> typename boost::enable_if<boost::is_same<T, int> >::type foo(T t) { }
source share