$include_dir="/home/hyper-archives/boost-users/include"; include("$include_dir/msg-header.inc") ?>
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.