Boost logo

Boost :

Subject: Re: [boost] [Bind] Interoperability of bind/mem_fn with transform_iterator
From: Samuel Debionne (debionne_at_[hidden])
Date: 2010-05-03 05:48:38


> On Fri, Apr 30, 2010 at 3:37 AM, Samuel Debionne<debionne_at_[hidden]> wrote:
>> Hello all,
>> I'm scratching my head about the correct way to use transform_iterator with
>> bind and mem_fn. In brief, bind and mem_fn return object functions that are
>> not Default Constructible, which means that, when used to construct a
>> transform_iterator, the resulting transform_iterator is not even a Trivial
>> Iterator.
>>
>> Most of the case, it's not a problem because the transform_iterator is never
>> default constructed... until some libs that do concept checking on their
>> template parameters are used. See the following code for exemple :
>
> Right, mem_fn_t is not DefaultConstructible, so a transform_iterator
> with mem_fn_t does not model ForwardTraversalIterator. Likewise with
> the return type of bind, which c++0x requires to be MoveConstructible
> (and CopyConstructible when it's args are) but not
> DefaultConstructible. In your specific example, however, you can still
> build a valid ForwardTraversalIterator by using boost::function to
> erase the return type of mem_fn. The same should work with bind.
>
> check(make_transform_iterator(
> foo_vec.begin(), function<size_t(foo&)>(mem_fn(&foo::get_id))));
>
> check(make_transform_iterator(
> foo_vec.begin(), function<size_t(foo&)>(mem_fn(&foo::id_))));
>
> Daniel Walker

Daniel, thank you for your solution. But doesn't type erasure avoid some
optimisations to take place (inlining) ? That could be a problem since
the function is called each time the iterator is deferred. I just did
some benchmarking that consists in accumulating a large range of foo id.
Here are the results with vc10 :

Boost.Function vs Hand Written : 9 time slower
Boost.MemFn vs Hand Written : 3.7 time slower
Boost.Function vs Boost.MemFn : 1.6 time slower

Anyway, in my opinion, using bind/mem_fn/lambda with transform_iterator
is a common use case. That would be great to have an option to add a
default constructor in those libs... or is it to risky ?
Samuel


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