Boost logo

Boost :

From: Giovanni Piero Deretta (gpderetta_at_[hidden])
Date: 2007-11-21 14:01:35


On Nov 21, 2007 7:27 PM, Dean Michael Berris <mikhailberis_at_[hidden]> wrote:
> On Nov 22, 2007 12:35 AM, Giovanni Piero Deretta <gpderetta_at_[hidden]> wrote:
> > std::map<int, std::vector<int> > map = ....;
> >
> > void foo(std::vector<int> const&);
> >
> > std::for_each(map.begin(), map.end(), bind(foo,
> > bind(boost::select<1>(), _1)));
> >
> > If you remove the const from the signature of foo, the example won't
> > compile at all. It is a bit elaborate to deduce the return value of a
> > generic tuple accessor in the most general case possible, but it can
> > be done. Anyways, fusion at_c already takes care of all the work.
> >
>
> Ah, you're referring to const-correctness and not returning a reference instead.
>
> In this case, I agree that this isn't acceptable in a lot of cases,
> thanks for pointing it out.
>
> Would it help if the current version of select<> would be called
> select_copy<> and select<> would return a correctly const-qualified
> reference instead?
>

I do not think so. There is no reason not to make select as general as possible.
Really, having select work in all cases is
not that hard. Implementing it is a good exercise in metaprogramming.
Start by looking at how boost::tuples::get computes its return value.

> I've also tried going with fusion::at_c in my initial attempt to get
> the correct result type, only that I run into problems with const
> correctness. I'll try my hand at it some other time though.
>

I've never really used Fusion in real programs (at work I'm stuck with an older
fusionless boost), but it should be const correct. If you have found
any bugs you
shuld report them.
Doesn't something like this work?

namespace ft = boost::fusion;

typename <int N>
struct at_c {

   // result_of protocol
   template<typename Sig>
   struct result;

   template<typename Seq>
   struct result<at_c(Seq&)> : fl::result_of::at_c<Seq, N> {};

   template<typename Seq>
   struct result<at_c(Seq const&)> : fl::result_of::at_c<Seq const, N> {};

   // actual operator() implementation
   template<typename Seq>
   typename fl::result_of::at_c<Seq, N>::type
   operator()(Seq& s) const {
       return fl::at_c<N>(s);
   }

   template<typename Seq>
   typename fl::result_of::at_c<Seq const, N>::type
   operator()(Seq const& s) const {
       return fl::at_c<N>(s);
   }

};

Of course this is completely untested. I didn't even try to compile it.

HTH,

--
gpd

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