
On 7/3/06, Thorsten Ottosen <thorsten.ottosen@dezide.com> wrote:
Well, we usually prefer "as efficient as possible" for libraries.
Again, this really is "as efficient as possible" for the given concept being modeled, and with specializations it provides just as efficient storage in containers as ptr_containers, only with the benefit of being true STL containers which are optimized and automatically used when working with a clone_ptr instantiation. On 7/3/06, Thorsten Ottosen <thorsten.ottosen@dezide.com> wrote:
If value semantics are desired, then why not provide them directly? Having polymorphic types with value semantics is fairly rare.
I'd say fairly rare simply because the tools to make it simple and efficient were never there. Think of a clone_ptr much more like a "smart object" rather than a "smart pointer," and its uses more similar to a nullable variant (note that nullability could even be toggled on and off via a template argument), only whose possible types are restricted to children of a specified type rather than by a finite number of explicitly specified types. This concepts makes working with polymorphic types much more consistent with the rest of the language. If you write a generic piece of code which takes in an instance of a type and stores a copy of it, it is simple to write generically in a way which may work intuitively for scalar types and most user-defined types -- all you do is take a reference to a const instance of the type and then use the copy constructor or assignment operator, nothing strange there. Now, let's say you have an abstract base class "shape" and you want to have that generic piece of code store instances of squares, circles, triangles, or any number of different types derived from shape. Again, this is not a horribly strange or uncommon concept. With clone_ptr, all you do is instantiate the type in question with clone_ptr< shape > and you get the value semantics you want. That's it -- no extra manually created types, and you don't have to make a special case in the generic code. In short, as described earlier, this is because clone_ptrs provide a simple way to have polymorphic types be used more consistently in generic code when compared to any other types in the language. Copying constructing a clone_ptr< shape > intuitively implies copying a shape, regardless of whether it is a square, circle, triangle, etc., just like copying an int means copying an integer. You get value semantics by default so that you may use such types in the same manner that you would any other types when working with generic code that is able to work with non-dynamically allocated objects with value semantics. I know I keep repeating myself, but I'm not sure exactly what it is that you don't understand. It is a lot more work to write an efficient/correct standard container
library, than to write the pointer container library on top of the standard library. So I don't agree with "simpler" here.
Simpler for users, not necessarily for the programmer of the library. Anyone who knows the STL knows how to use a given type in an STL container. Using a clone_ptr in an STL container can be done with the same code one would write with any other type, though with an optimized internal implementation entirely transparent to the user. All a programmer needs to learn is the interface of a clone_ptr and they get container optimizations without any extra work. Then, if they really need to optimize further, they can look at additional operations provided by the specializations.
Without a clone pointer type of concept, it is much more difficult to make
the code both generic and efficient.
Depends on your definition of efficient.
Alright, then by what definition of efficient are you refering to? It's just as efficient as using a ptr_container concerning speed and memory usage and it is easier to use in generic code when such semantics are required. Keep in mind that this is not intended as a replacement for ptr_containers, I just offer it as a suggested replacement for a subset of usage of them which can potentially make working with generic code much easier for both library writers and users.
optimizations remain as implementation details
rather than separate containers and any code already written does not have to be changed in order to take advantage of the optimizations.
If you think you doing programmers a favor by muddling the distinction between value semantics and polymorphic semantics, I think you're wrong.
I appreciate your criticisms, but I still disagree entirely. I believe you are missing the intended purpose of such a template and associated specializations. -- -Matt Calabrese