
On Nov 21, 2007 7:27 PM, Dean Michael Berris <mikhailberis@gmail.com> wrote:
On Nov 22, 2007 12:35 AM, Giovanni Piero Deretta <gpderetta@gmail.com> 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