Boost logo

Boost :

Subject: Re: [boost] [tuple] Functionals for tuple element access?
From: Eric Niebler (eniebler_at_[hidden])
Date: 2013-02-21 12:37:46

On 13-02-20 01:42 PM, Jan Hudec wrote:
> Hello All,
> Doing some heavy template work on collections of pairs and tuples I came
> across the need for functors returning tuple and pair members. So I looked
> whether Boost has anything like that, but couldn't find any.
> Now the functors can be written using bind like:
> bind(_1, &TupleType::get<3>);
> bind(_1, &PairType::first);
> except that requires explicitly mentioning the tuple/pair type. Trying to use
> simply
> &boost::tuples::get<3, WHAT?!?!?>
> even failed for me as boost::tuples::get is actually a 3-argument template
> based on boost::tuples::cons, which looks like implementation detail I better
> not rely on. Besides bost methods involve pointer-to-{function,member}, which
> might interfere with inlining.
> So I think it would be convenient to have functions like this somewhere in
> boost:
> template <int N>
> struct getter {
> template <typename X>
> struct result;
> template <typename F, typename T>
> struct result<F(T &)> {
> typedef BOOST_DEDUCED_TYPENAME element<N, T>::type &type;
> };
> template <typename F, typename T>
> struct result<F(T const &)> {
> typedef BOOST_DEDUCED_TYPENAME element<N, T>::type const &type;
> };
> template <typename T>
> BOOST_DEDUCED_TYPENAME element<N, T>::type &
> operator()(T &t) {
> return get<N>(t);
> }
> template <typename T>
> BOOST_DEDUCED_TYPENAME element<N, T>::type const &
> operator()(T const &t) {
> return get<N>(t);
> }
> };

There is something like this in Proto, where this kind of thing comes up
now and then. boost/proto/functional/fusion/at.hpp. It works on Fusion
vectors, not tuples, though.

> I would like to ask:
> 1. Would there be interest in adding this? Should I polish it up?


> 2. What would be good name and place for it (boost::tuples::getter)?
> 3. To support pairs, would it be preferred to specialize the N=0 and N=1
> cases (unfortunately I don't see how to handle the result struct without
> copy-paste) or define separate first_getter and second_getter or
> something like that?

Proto has "first" and "second": boost/proto/functional/std/utility.hpp.

> 4. The definition of result with const and non-const reference was enough
> for my uses in boost::transform_value_property_map, but I suspect it does
> not cover all necessary cases (I need non-reference and rvalue reference
> for C++11 too, right?)

In C++11, the nested result template is superfluous.

> My actual use-case was with boost::transform_value_property_map. I needed
> several property maps with the same set of keys, so I created one
> boost::associative_property_map with tuple values and splitted it to maps for
> the items using the above functor.
> Obviously nothing of this is needed with C++11 lambdas, but I am stuck
> having to support some obscure platforms like WinCE 4.2 and for it with
> MSVC++9.0.

I, for one, would love to see more algorithms implemented as polymorphic
function objects. They're more useful than function templates.

Eric Niebler

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