[boost-users][tuple] Tuple::get<0> as std::mem_fun_ref
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. template <typename LevelType> class LevelSetter { private: int nmb_of_elements; public: LevelSetter(int nmb_of_elements_) : nmb_of_elements(nmb_of_elements_) {} template <typename TrRange> std::vector<LevelType> set(TrRange range) { typedef typename TrRange::first_type TrIter; std::vector<LevelType> levels(nmb_of_elements); for (TrIter it = range.first; it != range.second; ++it) { levels[*it] = 0.0; } // much more complicated code return levels; } }; Let's call it: class MemFunRefTest { private: typedef float Scalar; typedef boost::tuple<int, Scalar> Tuple; typedef std::vector<Tuple> Fwd; typedef Fwd::iterator FwdIter; typedef std::pair<FwdIter, FwdIter> FwdRange; Fwd elements; public: MemFunRefTest() { elements.push_back(Tuple(0, 400.0)); elements.push_back(Tuple(1, 120.0)); elements.push_back(Tuple(2, 150.0)); } void fun() { FwdRange element_range = std::make_pair(elements.begin(), elements.end()); LevelSetter<Scalar> setter(elements.size()); setter.set(std::make_pair( boost::make_transform_iterator( element_range.first, std::mem_fun_ref(&Tuple::get<0>) ), boost::make_transform_iterator( element_range.second, std::mem_fun_ref(&Tuple::get<0>) ) ) ); } }; 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? Thanks, Miklos
Hi! Any updates on this? M. 2013/8/14 Miklós Tóth <spiralfuzet@gmail.com>
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.
template <typename LevelType> class LevelSetter { private: int nmb_of_elements; public: LevelSetter(int nmb_of_elements_) : nmb_of_elements(nmb_of_elements_) {}
template <typename TrRange> std::vector<LevelType> set(TrRange range) { typedef typename TrRange::first_type TrIter; std::vector<LevelType> levels(nmb_of_elements); for (TrIter it = range.first; it != range.second; ++it) { levels[*it] = 0.0; } // much more complicated code return levels; } };
Let's call it:
class MemFunRefTest { private:
typedef float Scalar; typedef boost::tuple<int, Scalar> Tuple; typedef std::vector<Tuple> Fwd; typedef Fwd::iterator FwdIter; typedef std::pair<FwdIter, FwdIter> FwdRange;
Fwd elements;
public: MemFunRefTest() { elements.push_back(Tuple(0, 400.0)); elements.push_back(Tuple(1, 120.0)); elements.push_back(Tuple(2, 150.0)); }
void fun() {
FwdRange element_range = std::make_pair(elements.begin(), elements.end());
LevelSetter<Scalar> setter(elements.size()); setter.set(std::make_pair( boost::make_transform_iterator( element_range.first, std::mem_fun_ref(&Tuple::get<0>) ), boost::make_transform_iterator( element_range.second, std::mem_fun_ref(&Tuple::get<0>) ) ) ); } };
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?
Thanks, Miklos
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
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@gmail.com>
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@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
participants (2)
-
Miklós Tóth
-
Nathan Crookston