Sorry for the misleading in the last answer, I thought it would be easier. Therefore, I will try to provide a complete solution here. A general approach to solving this type of problem is to write a helper template for the traits and use it together with enable_if (either C ++ 11, boost, or a manual implementation) to solve the specialization of the class:
Tre
A simple approach, not necessarily the best, but easy to write:
template <typename T> struct has_nested_Vec { typedef char yes; typedef char (&no)[2]; template <typename U> static yes test( typename U::Vec* p ); template <typename U> static no test( ... ); static const bool value = sizeof( test<T>(0) ) == sizeof(yes); };
The approach is simple, provide two template functions that return types of different sizes. One of them accepts a nested Vec type, and the other accepts ellipsis. For all those types that have a nested Vec , the first overload is the best match (ellipsis is the worst match for any type). For those types that do not have nested Vec SFINAE, they will discard this overload, and the ellipsis will be the only option left. So now we have a trait to ask if any type has a nested Vec type.
Enable if
You can use it from any library, or you can roll on your own, it's quite simple:
template <bool state, typename T = void> struct enable_if {}; template <typename T> struct enable_if<true,T> { typedef T type; };
When the first argument is false , the base template is the only option and does not have a nested type , if the condition is true , then enable_if has a nested type , which we can use with SFINAE.
Implementation
Now we need to provide a template and specialization that SFINAE will use only for those types with embedded Vec :
template<class T, class V = void> struct Functor { void operator()() const { std::cerr << "general" << std::endl; } }; template<class T> struct Functor<T, typename enable_if<has_nested_Vec<T>::value>::type > { void operator()() const { std::cerr << "special" << std::endl; } };
Whenever we create an instance of Functor with a type, the compiler will try to use the specialization, which in turn will create an instance of has_nested_Vec and get the true value passed to enable_if . For those types for which false , enable_if does not have a nested type type , so specialization will be discarded in SFINAE and the base template will be used.
Your special case
In your specific case, when it seems to you that you don’t need to specialize the whole type, but just an operator, you can combine three elements into one: a Functor , which sends one of two internal template functions based on Vec , eliminating the need for enable_if and feature class:
template <typename T> class Functor { template <typename U> void op_impl( typename U::Vec* p ) const { std::cout << "specialized"; } template <typename U> void op_impl( ... ) const { std::cout << "general"; } public: void operator()() const { op_impl<T>(0); } };