|
Boost : |
From: Simonson, Lucanus J (lucanus.j.simonson_at_[hidden])
Date: 2007-10-08 20:24:11
Joel wrote:
>Ok I posted something but realized I wasn't answering your question
>why inheritance (nor composition) is desirable when adapting.
>Here's a strong case...
>
>I have a legacy API with an opaque point type:
>
> struct point; // hah! opaque, details hidden
>
> // getter API
> float get_x(point const&);
> float get_y(point const&);
>
>Another example would be STL iterators where a pointer can
>model a random access iterator. Nope, you can't subclass from
>a pointer.
I think we aren't on the same wavelength here. My intention was to
allow a user to take their legacy type and pass it into my API (without
modifying the implementation of the legacy type) by providing the
adaptor ConceptMap that defines the points of customization that I
require to use their type in my code and by casting their type to its
subtype which I have defined. I still don't see how this is "intrusive"
nor what better alternative you have to offer. My application
developers were very clear when they gave me the requirements for what
they wanted in a library. "If something is conceptually a rectangle I
want to be able to use it as a rectangle, regardless of what else it
also happens to be or what API it provides to get access to its data."
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.
The way I'm doing it, you have to be explicit about what type you
conceptually want to treat the user type as. Is that overly onerous? I
just don't understand the nature of your objection. The fact that there
are other ways of achieving a similar effect in C++ doesn't explain to
me why I should use them instead of what I chose. So far my experience
(and users experience) with the library is that it does exactly what it
was designed to do with minimum of fuss, mostly related to compiler
errors that confuse users who aren't used to working with templates.
Luke
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk