
Now you have way to state "X can be viewed as an ellipse". But how would you state "if X can be viewed as a circle, then it can be viewed as an ellipse (in the way that ellipse_traits<X>::get_width() returns circle_traits<X>::get_radius()"?
This comes to say: if circle_traits is specialized for X, then ellipse_traits is specialized for X. And to forward the right functions in ellipse_traits<X> to the right ones in circle_traits<X>. enable_if can help doing that. Unfortunately I don't know if it's possible to know at compile-time if a specialization exists. But we can use a trick. I think I got to achieve what you're asking for: // the primary ellipse_traits template <class X, class Enable = void> struct ellipse_traits {}; // the primary circle_traits template <class X> struct circle_traits { // at this stage it's not specialized... typedef mpl::false_ specialized; }; // the following means litterally: " if circle_traits is specialized for X, // then ellipse_traits<X> exists and it's width() is defined in terms of the // circle's radius" template <class X> struct ellipse_traits< X, typename enable_if<typename circle_traits<X>::specialized>::type > { static void width() { circle_traits<X>::radius(); } }; // an ellipse class struct ellipse; // an ellipse has its own ellipse_traits, let's define them template <> struct ellipse_traits<ellipse> { static void width() { cout << "ellipse width" << endl; } }; // a circle class struct circle; // circle_traits of a circle template <> struct circle_traits<circle> { static void radius() { cout << "circle radius" << endl; } // now it's specialized typedef mpl::true_ specialized; }; int main(int, char** argv) { ellipse_traits<ellipse>::width(); ellipse_traits<circle>::width(); return 0; } The output is: ellipse width circle radius The "specialized" typedef is a bit weird, as it forces the user to sort of say "yes, I've really specialized it". But the goal is reached I think: I have never explicitly specialized ellipse_traits<circle>. I have only said that if circle_traits<X> exists then ellipse_traits<X> exists and ellipse_traits<X>::width() is circle_traits<X>::radius(), except if a better specialization of ellipse_traits<X> exists. And the compiler correctly understood what I meant when I asked for ellipse_traits<circle>::width(). Does anybody know a way to know if a specialization exists without using this kind of trick? Bruno