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