
Fernando wrote:
Nitpicking here, but, why is set() forwarding to set_() instead of doing this itself?
It has to do with maintainability. You see, I can easily change the design pattern because it is abstracted away from its usage. Only private functions of the PointConcept call the PointConceptMap functions, and I group those private functions together at the end of the class definition. Public functions only call the private functions or eachother and don't need to be changed if the design pattern or PointConceptMap implementation changes.
OK, you showed us how the pattern works. So, as a user I need to implement PointConceptMap<> and PointConcept<>, is that right? That seems like a lot of unnecesary work to me just to call a library. So, let me start with a concrete review now that I see some actual stuff. Why do I need to implement both PointConceptMap and PointConcept??
You don't, that is the point of the pattern. I implement PointConcept once for all points and the user only needs to implement the PointConceptMap for their type. My real PointConcept class has at least a hundred member functions plus stream operators. The PointConceptMap, in constrast, has only three functions. The idea is that the PointConcept gives a gratuitous, rich, and highly productive API, factoring out everything a person might do with a point or pair of points and providing those things as member functions. The PointConcept is the library, as far as points go.
Couldn't foo() be implemented like this instead? template <class T> void foo(T& t) { PointConceptMap<T>::PointSet(t ,HORIZONTAL ,PointConceptMap<T>::PointGet(t,VERTICAL) }
Of course, but then I would need to reimplement foo if I changed the interface. The way I do it I abstract the details of the concept map away from the implementation of functions that use it through the concept class.
That cuts down the adaptation burden on my side by half. It even gets rid >of the uggliest half (the one with the upcast). Add to that what I said about using free functions to leverage template
argument deduction and you get: template <class T> void foo(T& t) { PointSet(t,HORIZONTAL,PointGet(t,VERTICAL); }
Yes, that is pretty much the starting point for generic programming. I started there and added classes, abstractions and indirection until I came up with what I showed you. You can easily argue that I didn't *need* to do anything different from the simple, well know generic programming techniques. There are a hundred different ways to skin a cat. What we should be arguing about is whether what I'm getting for my trouble is worth it. Luke