|Posted by Kevin Bealer||PermalinkReply|
> Kevin Bealer wrote:
> > Walter Bright Wrote:
> >> I eventually ran across this article by Scott Meyers
> >> which made a lot of sense. It gives some good guidelines to use to
> make such decisions, and backs it up with reasoning that I find compelling.
> >> Isn't it funny how we've completed the circle? We went from all free
> functions in C, to all member functions in C++, and now back to free
> functions? <g>
> > I like Meyer's point here. My view is that classes provide the
> > following added value: they let you define a bunch of operations
> > without defining how they specifically will work.
> > The example I think of is what I believe are two mistakes in the C++
> > STL, the first is 'sort'. I think it "should" be a member function,
> > as vector::sort and list::sort have to be done differently for
> > efficiency reasons.
> I've found sort as a non-member function quite useful when I needed to change the code from a std::vector to a standard C array. A nice thing about non-member functions is they can work with privative types too.
Me too; now that I think about it there is also the nice aspect that you can sort part of an array/list/vector with it.
> > They give us the efficiency by making list::sort a member and vector
> > can be sorted with sort(v.begin(), v.end()). But I think that's a
> > mistake, since you can't write a good template that calls x.sort()
> > and expect it to do the best thing.
> I'm not sure what you what you are getting at here. I don't think a member function list::sort was a good idea.
There is an advantage to it, in that non-member function list needs to copy values but member function list can just switch pointers. This is important for a list of strings if you don't want the strings to be moved, or if you want to keep an iterator to a particular value from before to after the move.
I've never tested the difference in speed so I don't know how important this is, but I think sort() can sometimes take advantage of internal features of a class. That said, having both member and non-member seems okay to me (for this case).
But speed depends on the type T (as in vector<T>) as well. For some types, list<T>::sort might be faster and for others, vector<T>::sort. I seem to recall testing set<T> versus vector<T>::sort to see which worked faster and finding that one worked faster if T was int, and the other if T was string.
(Just one implementation of course.)
> > The other mistake (I think) is in the other direction, which is the
> 'extra' members that classes like string and vector have that give them
> personalities. For example, methods like "push_back()" and "rfind()"
> could be implemented externally for both string and vector, and it would
> result in less complexity AND more capability. (Maybe they wanted
> something like Boyer-Moore for string's find() related code?)
> > Kevin
> Perhaps these could be external however it would probably restrict optimizations and verifications that can be applied to these (without exposing more of the class then you need too). However it does seem odd to have find functions in 2 different places and my pet peeve with STL is that it has low discover-ability.
I guess what I'm thinking is that find(a.begin(), a.end(), value) could be written, and string::find(...) could also be written. If the most efficient find() is the external one, then string::find() could just use that. If not, it can use an different internal version.
My thinking is that users wanting speed can say s.find(...) and users wanting flexibility could say find(x.begin(), x.end(), ...) where x is any type. Maybe there's a nicer way to do this (I guess people use template specializations?)