Re: C++ Frequently Questioned Answers
Yossi Kreinin wrote:
Here's real code from a social network back-end :)
class Lamer { public: const LameComments& getLameComments(); };
void getTheMostLameComments(
vector<const LameComments*>& comments, //which type would you use?
const vector<Lamer>& lamers
)
{
//or we could use iterators...
for(int i=0; i<(int)lamers.size(); ++i)
{
const LameComments& lc = lamers[i].getLameComments();
if(lc.areTotallyPointless()) {
//lamers write lots of comments, better copy
//by reference... Has to be const - can't modify
//the lamer's precious comments, and we can't
//have vectors of references, so it's either a dumb
//const pointer or some non-standard smart pointer
comments.push_back(&lc);
}
}
}
I think this is a pretty common pattern with code massaging data
structures with even minor levels of nesting/indirection.
As you've discovered, just because it is a common pattern doesn't make
it good.
I think we should all ignore the completely unnecessary C cast and
move on.
This is a filter on top of a data structure. The C++ way of doing this
is to write an iterator that understands the filter rule. A bit more
advanced is to write an iterator adaptor which can be used to wrap
both const and non-const iterators on the underlying data structure.
I'm sure there's an implementation that takes a plug-in filter
predicate somewhere already.
They're not hard to write and have O(1) memory overhead compared to
the code shown above. They also side step many of the problems you
describe with the data types, const handling etc.
If you really need a copy of part of the container then
std::remove_copy_if is what you want. Again it sidesteps all of the
type problems, but I'd have to say that std::copy_if would be a more
useful name to have.
For this sort of code you want to be drawing your inspiration from
functional programming, not from OO programming.
BTW, Boost.Bind or Boost.Lambda will take care of the function
composition if you don't want to do it yourself.
K
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]