Boost logo

Boost :

From: John Torjo (john.lists_at_[hidden])
Date: 2004-03-01 01:00:53


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


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