Template specialization does not take into account inheritance hierarchy. For example, if I specialize a template for Base
and instantiate it with Derived
enable_if
is more flexibleI think you should really prefer the enable_if approach: it enables everything that you could require and more.
E.g. there might be cases where a Derived class is Liskov-Subsitutable for a Base, but you [cannot assume/donot want to apply] the same traits/specializations to be valid (e.g. because the Base is POD class, whereas Derived ands non-POD behaviour or somehting like that that is completely orthogonal to class composition).
enable_if
gives you the power to define exactly the conditions.
You could also achieve some middleground by implementing a traits class that derives some application-specific traits from general-purpose traits. The 'custom' traits could use the enable_if and meta-programming techniques to apply traits as polymorphically as you desire. That way, your actual implementations do not have to repeat some complicated enable_if/dispatch dance but instead can simply consume the custom-traits class (that hides the complexity).
I think some (many?) Boost libraries use the hybrid approach (I've seen it in some capacity where it bridges e.g. fusion/mpl, I think also various iterator traits in Spirit).
I personally like this approach because it can effectively isolate the 'plumbing' from the core-business of a library, making maintenance and documentation (!) a lot easier.