The std::is_abstract
is an example of a trait, and I like to follow the classic idiom of choice:
#include<iostream> #include<type_traits> template<bool> struct algorithm_selector { static void implementation() { std::cout<<"I am using the default implementation"<<std::endl; } }; template<> struct algorithm_selector<true> { static void implementation() { std::cout<<"I am using the 'custom' implementation"<<std::endl; } }; template<typename T> void foo() { algorithm_selector<std::is_abstract<T>::value>::implementation(); } struct ABC { virtual void bar() const = 0; }; struct Derived : ABC { }; struct Blah {}; int main() { foo<ABC>(); foo<Derived>(); foo<Blah>(); return 0; }
Compiled as (gcc 4.8.1) g++ example.cpp -std=c++11
gives the output:
I am using the 'custom' implementation I am using the 'custom' implementation I am using the default implementation
What I like about this is that it goes beyond the logic of * enable_if * (at least conceptually): it gives me an idiom that I can use to select arbitrary strategies at compile time. Most likely, this is a matter of preference, but for me this idiom is solid rock. In addition, check out the policy templates described in the book by Andrei Alexandrescu ; they are associated with this flexibility in compiled-time powered design.
source share