Boost logo

Boost :

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


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