
Peter Dimov wrote:
John Torjo wrote:
Imagine this:
struct test { int i; std::string s; }; std::vector<test> tests; // ... fill
void set(int & i, int val) { i = val }; int val = 10; // for each obj from vector, set obj.i = val; std::for_each( tests.begin(), tests.end(), bind(&decrement, bind(mem_fn(&test::i),_1), val);
Out of curiosity, do you really need this functionality?
Yup, that's how I came up with it ;) The truth is that not very often, but yes, I do need it at times.
The current implementation fails with the above example because of its "portable" nature (i.e. support for nonconforming compilers), but quality
That's why I proposed a totally different type (mem_data/const_mem_data).
implementations of the TR1 proposal (Hi Howard!) are actually supposed to handle this code both as written (typos aside), and with the shorthand
sorry 'bout the typos ;) #include <string> #include <vector> #include <algorithm> #include <boost/bind.hpp> using namespace boost; struct test { int i; std::string s; }; std::vector<test> tests; void set(int & i, int val) { i = val; } int main(int argc, char* argv[]) { std::for_each( tests.begin(), tests.end(), bind(&set, bind(mem_fn(&test::i),_1), 10) ); return 0; } on vc7.1: d:\boost\boost_latest\boost\boost\bind.hpp(273) : error C2664: 'void (int &,int)' : cannot convert parameter 1 from 'const int' to 'int &' Conversion loses qualifiers d:\boost\boost_latest\boost\boost\bind\bind_template.hpp(33) : see reference to function template instantiation 'R boost::_bi::list2<A1,A2>::operator ()<boost::_bi::bind_t<R,F,L>::result_type,void(__cdecl *)(int &,int),boost::_bi::list1<test &>>(boost::_bi::type<T>,F & ,A &)' being compiled with [ R=boost::_bi::bind_t<void,void (__cdecl *)(int &,int),boost::_bi::list2<boost::_bi::list_av_2<boost::_bi::bind_t<boost::_bi::unspecified,boost::_mfi::dm<int,test>,boost::_bi::list1<boost::_bi::list_av_1<boost::arg<1>>::B1>>,int>::B1,boost::_bi::list_av_2<boost::_bi::bind_t<boost::_bi::unspecified,boost::_mfi::dm<int,test>,boost::_bi::list1<boost::_bi::list_av_1<boost::arg<1>>::B1>>,int>::B2>>::result_type, A1=boost::_bi::list_av_2<boost::_bi::bind_t<boost::_bi::unspecified,boost::_mfi::dm<int,test>,boost::_bi::list1<boost::_bi::list_av_1<boost::arg<1>>::B1>>,int>::B1, A2=boost::_bi::list_av_2<boost::_bi::bind_t<boost::_bi::unspecified,boost::_mfi::dm<int,test>,boost::_bi::list1<boost::_bi::list_av_1<boost::arg<1>>::B1>>,int>::B2, F=void (__cdecl *)(int &,int), L=boost::_bi::list2<boost::_bi::list_av_2<boost::_bi::bind_t<boost::_bi::unspecified,boost::_mfi::dm<int,test>,boost::_bi::list1<boost::_bi::list_av_1<boost::arg<1>>::B1>>,int>::B1,boost::_bi::list_av_2<boost::_bi::bind_t<boost::_bi::unspecified,boost::_mfi::dm<int,test>,boost::_bi::list1<boost::_bi::list_av_1<boost::arg<1>>::B1>>,int>::B2>, T=boost::_bi::bind_t<void,void (__cdecl *)(int &,int),boost::_bi::list2<boost::_bi::list_av_2<boost::_bi::bind_t<boost::_bi::unspecified,boost::_mfi::dm<int,test>,boost::_bi::list1<boost::_bi::list_av_1<boost::arg<1>>::B1>>,int>::B1,boost::_bi::list_av_2<boost::_bi::bind_t<boost::_bi::unspecified,boost::_mfi::dm<int,test>,boost::_bi::list1<boost::_bi::list_av_1<boost::arg<1>>::B1>>,int>::B2>>::result_type, A=boost::_bi::list1<std::allocator<test>::value_type &> ] c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\algorithm(21) : see reference to function template instantiation 'boost::_bi::bind_t<R,F,L>::result_type boost::_bi::bind_t<R,F,L>::operator ()<std::allocator<_Ty>::value_type>(A1 &)' being compiled with [ R=void, F=void (__cdecl *)(int &,int), L=boost::_bi::list2<boost::_bi::list_av_2<boost::_bi::bind_t<boost::_bi::unspecified,boost::_mfi::dm<int,test>,boost::_bi::list1<boost::_bi::list_av_1<boost::arg<1>>::B1>>,int>::B1,boost::_bi::list_av_2<boost::_bi::bind_t<boost::_bi::unspecified,boost::_mfi::dm<int,test>,boost::_bi::list1<boost::_bi::list_av_1<boost::arg<1>>::B1>>,int>::B2>, _Ty=test, A1=std::allocator<test>::value_type ] d:\john\buff\testbind\testbind\testbind.cpp(20) : see reference to function template instantiation '_Fn1 std::for_each<std::vector<_Ty>::iterator,boost::_bi::bind_t<R,F,L>>(_InIt,_InIt,_Fn1)' being compiled with [ _Fn1=boost::_bi::bind_t<void,void (__cdecl *)(int &,int),boost::_bi::list2<boost::_bi::list_av_2<boost::_bi::bind_t<boost::_bi::unspecified,boost::_mfi::dm<int,test>,boost::_bi::list1<boost::_bi::list_av_1<boost::arg<1>>::B1>>,int>::B1,boost::_bi::list_av_2<boost::_bi::bind_t<boost::_bi::unspecified,boost::_mfi::dm<int,test>,boost::_bi::list1<boost::_bi::list_av_1<boost::arg<1>>::B1>>,int>::B2>>, _Ty=test, R=void, F=void (__cdecl *)(int &,int), L=boost::_bi::list2<boost::_bi::list_av_2<boost::_bi::bind_t<boost::_bi::unspecified,boost::_mfi::dm<int,test>,boost::_bi::list1<boost::_bi::list_av_1<boost::arg<1>>::B1>>,int>::B1,boost::_bi::list_av_2<boost::_bi::bind_t<boost::_bi::unspecified,boost::_mfi::dm<int,test>,boost::_bi::list1<boost::_bi::list_av_1<boost::arg<1>>::B1>>,int>::B2>, _InIt=std::vector<test>::iterator ] I'm not sure how this could be handled correctly (in any implementation).
bind(&test::i, _1) applied. (The & before 'decrement' is also redundant.)
You can persuade the current implementation to allow you to modify a member with bind<int&>(mem_fn(&test::i), _1).
Good point! Up until now never thought of using bind like this ;) // compiles ok std::for_each( tests.begin(), tests.end(), bind(&set, bind<int&>(mem_fn(&test::i),_1), 10) ); Best, John