This is a kind of concept check.
We have a type predicate for the type T that saysif the type T is a concept X.
It will be, if the type T is derived from X, or if we explicitly say that.
#include <type_traits> #include <iostream> struct shape_concept {}; struct circle_concept : public shape_concept {}; struct square_concept : public shape_concept {}; //By default check if Concept is base of T template<class T, class Concept> struct is_concept_model : public std::is_base_of<Concept, T> {}; //Formula for circle_concept template<class T> typename std::enable_if<is_concept_model<T, circle_concept>::value, double>::type Area(const T& o) { const double pi = 3.14; return pi * o.radius() * o.radius(); } //Formula for square_concept template<class T> typename std::enable_if<is_concept_model<T, square_concept>::value, double>::type Area(const T& o) { return o.side() * o.side(); } //Error if T is not a shape_concept model template<class T> typename std::enable_if<!is_concept_model<T, shape_concept>::value, double>::type Area(const T& o) { static_assert(false, "type T must map shape_concept"); return 0; } struct MyCircle1 : public circle_concept { double radius() const { return 1.5; } }; struct MyCircle2 { double radius() const { return 2.0; } }; //We explicitly will say that MyCircle2 is a model of circle_concept //and that MyCircle2 is a model of shape_concept should be automatic! template<> struct is_concept_model<MyCircle2, circle_concept> : public std::true_type {}; template<> struct is_concept_model<MyCircle2, shape_concept> : public std::true_type{}; struct MySquare1 : public square_concept { double side() const { return 2.0; } }; struct MySquare2 { }; int main() { MySquare1 s1; MySquare2 s2; MyCircle1 c1; MyCircle2 c2; std::cout << Area(s1) << std::endl; std::cout << Area(c1) << std::endl; std::cout << Area(c2) << std::endl; // std::cout << Area(s2) << std::endl; }