Boost logo

Boost Users :

Subject: Re: [Boost-users] [boost-users][tuple] Tuple::get<0> as std::mem_fun_ref
From: Miklós Tóth (spiralfuzet_at_[hidden])
Date: 2013-08-30 05:32:30


Hi Nate,

Thanks for the response.
I couldn't manage to compile the first solution (with the cast) but the
second worked well.
Thanks again.

Miklós

2013/8/29 Nathan Crookston <nathan.crookston_at_[hidden]>

> Hi Miklós,
>
> Sorry for missing your first email.
>
> Miklós Tóth wrote:
>
>> Hi!
>>
>> I have a problem with std::mem_fun_ref and boost::tuple. Here is my code:
>> I have small LevelSetter class. It makes a level vector indexed by a
>> transform_iterator value.
>>
>
> <snip code>
>
>
>> When I try to compile i get:
>>
>> error: call of overloaded 'mem_fun_ref(<unresolved overloaded function type>)' is ambiguous
>> candidates are:
>> c:\mingw-4.6\bin\..\lib\gcc\i686-pc-mingw32\4.6.1\..\..\..\..\include\c++\4.6.1\bits\stl_function.h:697: std::mem_fun_ref_t<_Ret, _Tp> std::mem_fun_ref(_Ret (_Tp::*)()) [with _Ret = int&, _Tp = boost::tuples::cons<int, boost::tuples::cons<float, boost::tuples::null_type> >]
>> c:\mingw-4.6\bin\..\lib\gcc\i686-pc-mingw32\4.6.1\..\..\..\..\include\c++\4.6.1\bits\stl_function.h:702: std::const_mem_fun_ref_t<_Ret, _Tp> std::mem_fun_ref(_Ret (_Tp::*)()const) [with _Ret = const int&, _Tp = boost::tuples::cons<int, boost::tuples::cons<float, boost::tuples::null_type> >]
>>
>>
>> What am I missing?
>>
>> Those problems are usually due to the compiler not knowing which
> overload of the function to use. That can be solved using a static_cast
> (the bind documentation explains it pretty well [1])
>
> Here's a solution that casts appropriately:
>
> #include <boost/range/adaptors.hpp>
> #include <boost/range/algorithm.hpp>
> #include <boost/tuple/tuple.hpp>
> #include <functional>
> #include <iostream>
> #include <vector>
>
> using boost::adaptors::transformed;
>
> void print(int i)
> { std::cout << i << std::endl; }
>
> int main()
> {
> typedef boost::tuple<int, float> Tuple;
> std::vector<Tuple> v;
> v.push_back(Tuple(5, 4.));
> v.push_back(Tuple(6, 3.));
> v.push_back(Tuple(7, 2.));
>
> boost::for_each(v | transformed(std::mem_fun_ref(
> static_cast<int& (Tuple::*)()>(&Tuple::get<0>))), print);
> }
>
> (It should work the same with transform_iterator, since I believe
> transformed eventually just forwards to it.)
>
> To avoid casting, you might consider the following, using fusion and
> phoenix:
>
> #include <boost/fusion/adapted/boost_tuple.hpp>
> #include <boost/phoenix.hpp>
> #include <boost/phoenix/fusion/at.hpp>
> #include <boost/range/adaptors.hpp>
> #include <boost/range/algorithm.hpp>
> #include <boost/tuple/tuple.hpp>
> #include <iostream>
> #include <vector>
>
> using boost::adaptors::transformed;
> namespace px = boost::phoenix;
> using px::arg_names::_1;
>
> void print(int i)
> { std::cout << i << std::endl; }
>
> int main()
> {
> typedef boost::tuple<int, float> Tuple;
> std::vector<Tuple> v;
> v.push_back(Tuple(5, 4.));
> v.push_back(Tuple(6, 3.));
> v.push_back(Tuple(7, 2.));
>
> boost::for_each(v | transformed(px::at_c<0>(_1)), &print);
> }
>
> HTH,
> Nate
>
>
> [1] <
> http://www.boost.org/doc/libs/1_54_0/libs/bind/bind.html#err_overloaded>
>
>
> _______________________________________________
> Boost-users mailing list
> Boost-users_at_[hidden]
> http://lists.boost.org/mailman/listinfo.cgi/boost-users
>



Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net