
On 7/6/06, Thorsten Ottosen <thorsten.ottosen@dezide.com> wrote:
The problem I have with that is that such "generic" code cannot assume anything about the stores type. It must be manipulation of the container itself.
Even for such tasks I can easily imagine problems depending on how you specify clone_ptr. (For example, does < compare the pointee=).
No, it doesn't compare the pointee. You still work with the object through indirection. Performance-wise, even doing something like
container::value_type v = cont.back(); cont.push_back( v );
is going to be very efficient for vector<int>, but very costly for T=clone_ptr<U>. So the amount of generic algorithms you intend to write at the container level is certainly not easy.
And? You have the same "problem" with any complex user-defined type. This is not a special case for clone_ptrs. Lot's of types internally use dynamic memory allocation or have otherwise complex copy operations -- this is nothing new. So what happens with those complex user-defined types? Such code still compiles, as it should, it works correctly, and it remains up to the user to decide if it is fast enough for his given situation. clone_ptr has all of the same characteristics as any relatively complex object used in generic code, only it also has the benefit of easily allowing for specializations of generic code which use instantiations of it, not to mention the fact that it allows one to easily adapt polymorphic types to be able to be used in such generic code to begin with. And consider sort() on a collection of clone_ptr<T>. This will be
immensely expensive without move-semantics whereas ptr_vector<T>::sort() stays efficient.
Like your other statements, "immensely expensive" is entirely relative to the situation and you should not be assuming at the library level that no one should ever do it. It logically makes sense, it's not slow for all situations, and it makes generic code much easier to write. Not only that, but once again, sorting a range of clone_ptrs is no more inneficient than sorting a range of any relatively complex type. What's more is, it's also entirely possible for the clone_ptr library to specialize std::sort for standard container iterators of clone_ptrs, therefore once again giving you just as efficient code as ptr_containers, but with entirely generic code. And I'm still convinced that specializing the entire container library
from std:: is a very bad idea, maintenance wise and header-wise. Your header for clone_ptr would be *huge*, because if you don't include all container specializations, one risk that the specialization is not picked up.
At least we agree on this. I have worked with C++, Java and C# for years, also on big projects, and
object cloning have never been a major part of the code, although the code was OO all the way. Never. Once in a while you need to copy the entire colelction of shapes or what-ever. But it's never the main application.
Right, it's not often that it is a major part of a given project, though the fact that you say "major" does show that it does happen and has even happened to you. Sure it's not needed for every single project, but such is the case for most libraries. I've only found myself using variants in a few projects, I've never used boost::any, I personally don't have a need for uBLAS, and I don't use all of the algorithms in the standard library. Just because a library or feature of a library isn't a central part to many applications does not mean that it is not useful and it certainly doesn't mean that it is not logically correct nor that its functionality should be excluded. -- -Matt Calabrese