
Bruno wrote:
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?
I was in the middle of typing up a proposal for what Bruno suggests, but had a different solution to knowing whether a specialization exists. My solution was simply to register the conceptual type of the object with a meta function, which indicates both that the corresponding traits should also be defined as well as an easy way to tell what conceptual type that object most closely models. template <typename T1, typename T2> struct SFINAE_is_same_type {}; template <typename T> struct SFINAE_is_same_type<T, T> { typedef void type; } template <typename T> struct geometry_concept {}; struct circle_concept {}; struct circle_data_type {}; template <> struct geometry_concept<circle_data_type> { typedef circle_concept type; }; template <class X> struct ellipse_traits< X, typename SFINAE_is_same_type< typename geometry_concept<X>::type, circle_concept>::type > { static void width() { cout << "another way to get at ellipse width" << endl; } }; I'm not sure which way is better, but I provide the geometry_concept meta-function anyway to use for tag dispatching/SFNAE purposes. Regards, Luke