From: John Torjo (john.lists_at_[hidden])
Date: 2004-03-08 03:41:33


>
> On a Metrowerks version which has not been announced (much less
> released):
>
> #include <string>
> #include <vector>
> #include <algorithm>
> #include <bind>
> using namespace std::tr1;
> using namespace std::tr1::placeholders;
> 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;
> }
>
Sorry, I mis-explained.
For boost::bind, the above works like a bliss.

It will have problems working with other code, that uses result_type.
For example, boost::transform_iterator:

#include <boost/bind.hpp>
#include <boost/iterator/transform_iterator.hpp>
using namespace boost;
#include <algorithm>
#include <vector>
#include <string>

struct test { std::string s; };

void clear_s( std::string & s) { s.erase(); }

int main(int argc, char* argv[])
{
    std::vector<test> v;
    std::for_each(
        // of course, it would be simpler to use Range Template Library :D
        make_transform_iterator(v.begin(),mem_fn(&test::s)),
        make_transform_iterator(v.end(),mem_fn(&test::s)),
        clear_s);

    return 0;
}

c:\Program Files\Microsoft Visual Studio .NET
2003\Vc7\include\algorithm(21) : error C2664: 'void (std::string &)' :
cannot convert parameter 1 from 'const std::string' to 'std::string &'
        Conversion loses qualifiers
        d:\john\buff\testbind2\testbind2\testbind2.cpp(23) : see
reference to function template instantiation '_Fn1
std::for_each<boost::transform_iterator<UnaryFunction,Iterator,Reference,Value>,void(__cdecl
*)(std::string &)>(_InIt,_InIt,_Fn1)' being compiled
        with
        [
            _Fn1=void (__cdecl *)(std::string &),
            UnaryFunction=boost::_mfi::dm<std::string,test>,
            Iterator=std::vector<test>::iterator,
            Reference=boost::use_default,
            Value=boost::use_default,
            
_InIt=boost::transform_iterator<boost::_mfi::dm<std::string,test>,std::vector<test>::iterator,boost::use_default,boost::use_default>
        ]

That's why I said we should have two classes - one that defines:
    typedef R const & result_type;

and one that defines:

    typedef R & result_type;

So you can clearly choose if you treat your sequence as const or not.

Best,
John