Boost logo

Boost :

Subject: Re: [boost] Design conventions; passing functors
From: Joachim Faulhaber (afojgo_at_[hidden])
Date: 2008-11-16 09:07:57


2008/11/15 vicente.botet <vicente.botet_at_[hidden]>:
> ----- Original Message -----
> From: "Joachim Faulhaber" <afojgo_at_[hidden]>
> To: <boost_at_[hidden]>
> Sent: Thursday, November 06, 2008 6:28 PM
> Subject: Re: [boost] Design conventions; passing functors
>
>
>>
>> 2008/11/6 Steven Watanabe <watanabesj_at_[hidden]>:
>
>>>> 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


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