Boost logo

Boost :

From: David Abrahams (dave_at_[hidden])
Date: 2005-05-08 20:38:22

I just added an index_result metafunction that was requested during
the review, for getting the result of a named parameter lookup,
possibly with a default or a lazy default.

Whereas previously, you would write the following to implement your
function with named parameters,

  template<class Params>
  void f_impl(const Params& p)
        , p[value || boost::bind(&value_default) ]
        , p[index | 999 ]

now you have the option to write something like this:

  template<class Params>
  void f_impl(const Params& p)
      typename boost::parameter::index_result<
        Params, struct name_>::type& n = p[name];

      typename boost::parameter::index_result<
        Params, struct value_, double
>::type const& v = p[value || boost::bind(&value_default) ];
      typename boost::parameter::index_result<
        Params, struct index_, int
>::type const& i = p[index | 999];

The problem, which you may have noticed, is that in the latter case
you may be creating dangling references to destroyed rvalues. In the
case of the index parameter above, the rvalue 999 gets bound to a
const reference that then *passes through* the operator[] and
initializes i. Since p[index | 999] returns a const reference and not
a value, i is bound directly to the original rvalue 999 which is
destroyed at the end of the full expression.

The question is, what should we do about this? It turns out to be
surprisingly hard to write the declarations of these temporary
variables so they work in all cases. For example, v had to be a
const& because in one case index_result<...>::type turned out to be

  char const[4]

and when the default is used, it's


with p[value || ...] returning a double rvalue (by value).


Dave Abrahams
Boost Consulting

Boost list run by bdawes at, gregod at, cpdaniel at, john at