Boost logo

Boost Users :

From: Peter Dimov (pdimov_at_[hidden])
Date: 2007-01-16 19:31:15


Alan M. Carroll wrote:
> I am having a problem with Boost.Bind (1.33.1). Consider the
> following simplified code:
>
> struct Bob {
> void func() { }
> };
> void bob_test() {
> typedef std::map<int, Bob> BobMap;
> BobMap bob_map;
> std::for_each(bob_map.begin(), bob_map.end(),
> bind(&Bob::func, bind(&BobMap::value_type::second, _1)));
> }
>
> This fails to compile under DevStudio 8. The problem is the outer
> bound functor expects (Bob* const) but is passed (Bob const*).
>
> This seems a straight forward use -- call the "func" method on every
> Bob instance in the map. I can get this to compile if I change the
> inner bind to "bind<Bob&>(...)". Shouldn't the default return type of
> the binding of (R T::*) be (R&)? I looked through the bind and mem_fn
> documentation and didn't see any mention of that. The .* operator
> applied to a non-const T and a (R T::*) returns (R&), so it is
> implied that mem_fn of a data member does as well.

Unfortunately boost::bind is a bit simplistic and always has a fixed return
type. Since when the member pointer is bound there is no way to determine
whether it will be applied to a const or a non-const T, the default is the
conservative R const& that can be used with both (but may cause failures
upstream if the outer bind expects a R&.) I assumed that writing bind<R&>
won't be that big of a deal in the relatively rare cases where it's needed.

> Also, why does the error message refer to pointers and not
> references? Is that an artifact of compiler argument matching
> failure?

It's an implementation artifact of mem_fn. The proper overload taking T&
doesn't match (the argument is const) and another unrelated overload (used
for derived types and smart pointers) is selected.


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