Boost logo

Boost :

Subject: Re: [boost] Design conventions; passing functors
From: David Abrahams (dave_at_[hidden])
Date: 2008-11-29 11:19:51


on Sun Nov 16 2008, "Joachim Faulhaber" <afojgo-AT-googlemail.com> wrote:

> 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."

Except that there's a well-known convention that function objects and
iterators (and probably some other things) should be
lightweight-copyable.

> (3) Passing functors by value stands in direct contradiction to the
> well established rule to pass class obects by (const)-reference.

That rule is wrong when objects need to be copied anyway. Pass-by-value
+ swap (or move) into place is the best practice in that case, because
it saves copies of rvalues on known real compilers and costs no extra
copies of lvalues.

> (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.

A good choice that is both forward-looking and compatible with legacy
code is to implement and document move semantics support (or a
swappability requirement), and pass by value unless there's no need for
an eventual copy.

> 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.

Extra copies of rvalues can be expensive, and function objects are often
rvalues.

-- 
Dave Abrahams
BoostPro Computing
http://www.boostpro.com

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk