Rooters, I was just trying to write a nice filtered collection template: template <class T, class Collection=TOrdCollection> Collection FilteredList(const TCollection &l) { Collection mylist; // Maybe should specialize with a preset capacity // for classes which have that facility... // but that's an optimization for later. TIter Next(&l); while (TObject *obj=Next()) { if (T *filtered_obj = dynamic_cast<T *>(obj)) { mylist.Add(filtered_obj); } } return mylist; } for use in routines that want to find the best object in a collection satisfying certain criteria; and I didn't want to write the code over and over in different filtering places. Aha, a template, I thought -- and a smart compiler will optimize out the copy constructor of the return value (as its allowed to do) in most cases, so I don't feel too bad about returning the object itself since I will only construct it once, really. Then I compiled and discovered that TCollection::TCollection(TCollection &) is *private* and not implemented, and thus this is true also for all its descendants. I understand this idiom as preventing copying (even in cases where the constructor could be optimized out) -- but why? The comment says 'TCollections are too sensitive', but I don't see how -- the collections don't own their contents, you're just copying a bunch of pointers. Sure, it might lead to a few inefficiencies if people use it incorrectly or without thinking about the copy constructors... but that's not a reason to PREVENT the activity, and even then with modern computing power the copying of a few, or a few hundred, or even a few thousand pointers is of very little impact except inside inner loops, where profiling ought to catch these kinds of mistakes. Is there something terribly dangerous about copying collections that I'm missing? Obviously, I can't use Clone() -- I certainly don't want to copy ALL the contents, just the pointers -- and I don't want to return pointers, since I don't want the user to be forced to delete the pointer afterwards (despite the fact that a lot of ROOT code works this way, I find this idiom odious and to be avoided if at all possible*). So what should I do? N.B. I was trying to do this as a way to go around (in a slightly more inefficient way) the problem I mentioned some weekes ago with TIter and TIterator, which prevents you from defining TIterator classes not connected 1-to-1 with a TCollection class. The combination of not being able to do either, and being prevented by local policy from using STL containers (which do supply copying) is producing a great deal of frustration here. George Heintzelman gah@bnl.gov * And besides, it makes this really nice syntax impossible: GetBestFrom(FilteredList<TSomeClass>(mylist)); Instead, I have to make a local pointer, pass it, and delete it. Never mind exception safety, of course... GAH
This archive was generated by hypermail 2b29 : Tue Jan 02 2001 - 11:50:32 MET