
AMDG Simonson, Lucanus J <lucanus.j.simonson <at> intel.com> writes:
If you have a legacy prism type CPrism and it is conceptually a rectangle with the additional z axis data you can pass it into an API I have defined that expected a rectangle: apiExpectingRectangle(RectangleConcept<CPrism>::mimic(myCPrism)); Or you can pass it into an API expecting a prism: apiExpectingPrism (RectangularPrismConcept<CPrism>::mimic(myCPrism)); Or you can pass it into an API that is overloaded to expect either a rectangle or a prism: apiExpectingRectangleOrPrism(RectangleConcept<CPrism>::mimic(myCPrism)); apiExpectingRectangleOrPrism(RectangularPrismConcept<CPrism>::mimic(myCP rism)); and get different behaviors out of that api depending on which type you told it to model the data as.
Suppose that I want to write template<class Rectangle, class T> void move_up(Rectangle&, T offset); to modify a rectangle in place. if I need to copy the rectangle this isn't going to work. The alternative is to have some set of metafunctions/traits/free functions that allow one to operate directly on the object. template<class T> struct is_rectangle : boost::mpl::false_ {}; // default is not a rectangle template<class T> struct rectangle_get_x; template<> struct rectangle_get_x<CRect> { typedef unsigned short result_type; result_type operator()(const CRect& rect) const; }; // etc. Now generic functions can operate directly on a CRect without making any copies. Then, apiExpectingRectangleOrPrism can be declared as template<class T> typename boost::enable_if<is_rectangle<T> >::type apiExpectingRectangleOrPrism(const T&); template<class T> typename boost::enable_if<is_prism<T> >::type apiExpectingRectangleOrPrism(const T&); If the type passed to this function is either a rectangle or a prism but not both the call is unambiguous. If the type that you want to pass in is both then you can disambiguate by creating an adapter. template<class T> struct rectangle_adapter { T impl; }; Alternately, and probably better, you can define the real functions using different names and have the generic api forward. template<class T> void apiExpectingPrism(const T&); template<class T> typename boost::enable_if<is_prism<T> >::type apiExpectingRectangleOrPrism(const T& t) { return(apiExpectingPrism(t)); } // similarly for rectangle In Christ, Steven Watanabe