Boost logo

Boost :

Subject: [boost] Design conventions; passing functors
From: Joachim Faulhaber (afojgo_at_[hidden])
Date: 2008-11-06 11:17:27


Hi,

I am pondering about functor passing. Functors occur in my
library (ITL) e.g. for the aggregation of associated values
on insertion in interval_maps (aggregation on overlap):

template<class Domain, class Codomain, ...>
class interval_map{
  ...
  //(1) My current implementation is this:
  // Combinator is the aggregating functor template,
  // instantiated at compiletime
  template<template<class>class Combinator>
  interval_map& add(const value_type& value_pair)
  { /*Combinator template passed or instantiated somewhere*/ }
  ...
}

//I like this definition, because it's abstract:
// The functor has to be a matching template e.g. inplace_max
interval_map<int,int> m;
m.add<inplace_max>(some); //(1)

template<class Domain, class Codomain, ...>
class interval_map{
  //(2) The more traditional definition
  template<class Combinator>
  interval_map& add(const value_type& value_pair)
  { /*Combinator type passed or called somewhere*/ }
  ...

m.add<inplace_max<int> >(some); //(2)

I prefer (1) but both definitions (1) and (2) are purely
static denotations. To have adaptable functors or functors
that can have states, like in ...

m.add(some, max_under(42));

... I am afraid I have to say sayonara to definition (1)
and use this instead:

template<class Domain, class Codomain, ...>
class interval_map{
  //(3) Adaptable functor
  template<template<class>class Combinator>
  interval_map& add(const value_type& value_pair,
                    const Combinator<Codomain>& combine)
  { /*combine functor passed or called somewhere*/ }

Now, there seems to be a convention from the STL that functors
shall be passed BY VALUE.

  template<template<class>class Combinator>
  interval_map& add(const value_type& value_pair,
                    Combinator<Codomain> combine);
                                        
This is stated in [Sutter & Alexandrecu 2005, C++ Coding
Standards] item 89:
"Function objects are modeled on function pointers. Like
function pointers, the convention is to pass them by value.
All of the standard algorithms pass objects by value, and
your algorithms should too."

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. So I browsed through
some boost libraries and found that functors are passed by
reference there (e.g. accumulators, fusion).

Final question: What is the boost standard on passing functors,
that I can adapt to?

Cheers
Joachim


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