
2008/11/15 vicente.botet <vicente.botet@wanadoo.fr>:
----- Original Message ----- From: "Joachim Faulhaber" <afojgo@googlemail.com> To: <boost@lists.boost.org> Sent: Thursday, November 06, 2008 6:28 PM Subject: Re: [boost] Design conventions; passing functors
2008/11/6 Steven Watanabe <watanabesj@gmail.com>:
I do not really understand this convention and feel some resistance to follow it. In addition the call by value implementation can (and will) lead to heavy inefficiency by unaware usage of fat functors.
The assumption is that function objects are not fat. If you have a large function object, it is always possible to create another function object that just stores a reference to the original function object.
Is not this the role of boost::ref?
Unfortunately the assumption can not be that all programmers are always aware of the many c++ intricacies.
There's a rule stated by Scott Meyers in one of his books: "Make your classes easy to use correctly and difficult to use incorrectly."
If the parameter do a copy is is very difficult to use incorrectly, either you function is CopyConstructible and works, or if not it not compiles. If the functor is heavy to copy it is up to the functor designer to forbid copy construction. Optionaly the Functor can implement move semantics, but this is not absolutely needed. In any case to can wrap it with boost::ref.
Thanx for the hint to boost::ref
Am I missing something basic?
I have found an article of Scott Meyers on his "most important general design guideline in my arsenal": "Make interfaces easy to use correctly and hard to use incorrectly" (Mietucahatuin ;-) http://www.aristeia.com/Papers/IEEE_Software_JulAug_2004_revised.htm I am still not convinced to pass my functors by value and I think it violates Mietucahatuin. (1) It makes additional assumptions: The client of the software has to be aware, that passing a fat functor causes expensive copies, not only at the point of passing the functor to a library function but also in internal calls. That means she has to have knowledge about implementation details of the library code. That is a violation of the principle of information hiding. (2) The client of the software has to remember complex knowledge in order to use the code correctly: If she wishes to use a rich state she has to remember to implement the functor using the pimpl idiom or move semantics. Yet Scott Meyers writes in the article above, and I think he's right: "But interfaces that rely on clients remembering to do something are easy to use incorrectly." (3) Passing functors by value stands in direct contradiction to the well established rule to pass class obects by (const)-reference. (4) It takes the burden of facilitating correct use away from the libraries author and puts it on the libraries client, which also violates Meyer's Mietucahatuin-rule. Sorry if I've got too apodictic. I am mainly interested in a good decision for my own library code. As written earlier in this thread, I would prefer to pass functors const reference, and without additional wrappers (which is done by other boost libraries too). I do not call std::algorithms internally. Please tell me, if there are strong arguments against that. Cheers Joachim