Boost logo

Boost Users :

From: Hughes, James (jhughes_at_[hidden])
Date: 2007-06-11 09:20:03


> -----Original Message-----
> From: boost-users-bounces_at_[hidden]
> [mailto:boost-users-bounces_at_[hidden]] On Behalf Of Küppers, Ben
> Sent: 11 June 2007 13:17
> To: boost-users_at_[hidden]
> Subject: Re: [Boost-users] [bind] Help with
> functionalcompositionofshared_ptr::use_count in std::map
>
> > map<string, shared_ptr<data> > Fred;
> >
> > RemoveIf(Fred.begin(),
> > Fred.end(),
> > boost::bind(&map<string, shared_ptr<data>
> > >::value_type::second::unique, _1)
> > )
>
> James,
>
> remove_if requires an assignment operator on the operated
> type but the value_type of a map is defined as std::pair<
> const T1, T2 >. The const on the first type will cause any
> assignment to fail. In other words, you can't use remove_if on a map.
>
> That said, in order to fix your bind you would need two
> functors. The type passed to the bind is the value_type of
> the map which is by definition a pair. You need to first
> invoke a functor on the pair to extract the second member and
> then call the member unique on the resulting smart pointer.
> In order to do so you'll need to write your own extractor,
> because the STL does not provide a functor to obtain the
> "second" field from a pair (I haven't found one in boost either).
>
> template< class Pair >
> struct second_of : std::unary_function< Pair, typename
> Pair:second_type > {
> typename Pair::second_type opertator()( const Pair&
> the_pair ) const {
> return the_pair.second;
> }
> };
>
> std::for_each(
> Fred.begin(),
> Fred.end(),
> boost::bind(
> boost::shared_ptr< data >::unique,
> boost::bind(
> second_of< std::map< std::string, boost::shared_ptr<
> data > >::value_type >(), _1 ) ) );
>
> Note that you can call for_each as it does not require the
> assignment operator.
>
> Hope this helps,
>
> Ben
>
>
>

Thanks Ben,

That explains the problems. As it turns out, I reckon that the following, which completely avoids any bind stuff, is easier to read and understand...its a pity I chose such a dodgy example as a first bind effort!!!!

typedef std::map< std::string, boost::shared_ptr<data> > cachetype;

cachetype Cache; // and add some stuff to it

cachetype::iterator pos;

for (pos = Cache.begin(); pos != Cache.end();)
{
   if (pos->second.unique())
        Cache.erase(pos++);
   else
        ++pos;
}

See page 205 in The C++ Standard Library by Josuttis for reasoning.

James

This message (including any attachments) contains confidential
and/or proprietary information intended only for the addressee.
Any unauthorized disclosure, copying, distribution or reliance on
the contents of this information is strictly prohibited and may
constitute a violation of law. If you are not the intended
recipient, please notify the sender immediately by responding to
this e-mail, and delete the message from your system. If you
have any questions about this e-mail please notify the sender
immediately.


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net