Boost logo

Boost Users :

From: Peter Dimov (pdimov_at_[hidden])
Date: 2005-07-26 15:18:10


Nat Goodspeed wrote:
> We have a class that contains a std::map. This class wants to provide
> its clients with iterators over just the values in the map, hiding the
> fact that there's a map under the covers at all. transform_iterator
> seems like just the ticket, and with Boost 1.31 we used these methods:
>
> typedef std::map<KEYTYPE, VALUETYPE> MapType;
>
> typedef boost::transform_iterator<
> boost::function<const MapType::mapped_type&(const
> MapType::value_type&)>,
> MapType::const_iterator
> > const_iterator;
>
> const_iterator begin() const
> {
> return boost::make_transform_iterator(mymap.begin(),
> boost::bind(&MapType::value_type::second, _1));
> }
>
> const_iterator end() const
> {
> return boost::make_transform_iterator(mymap.end(),
> boost::bind(&MapType::value_type::second, _1));
> }
>
> The above compiled cleanly, except when it caused a compiler ICE, and
> the instances that compile seem to run okay.
>
> Now we're trying to upgrade to Boost 1.32 -- I know, a little late in
> the 1.32 lifespan. The same code now produces an ominous warning (full
> text at end of message):
>
> c:/videobranch\boost\boost\function\function_template.hpp(111) :
> warning C4172: returning address of local variable or temporary
>
> When it finally gets around to mentioning a line number in our own
> source code, the indicated line is the return statement in the above
> begin() method.

The change that's breaking your code is (unfortunately) in boost::bind, not
in transform_iterator. In 1.31, boost::bind(&MapType::value_type::second,
_1) returns a reference. In 1.32, the same construct returns by value.

You can change

boost::function<const MapType::mapped_type&(const MapType::value_type&)>

to

boost::function<MapType::mapped_type(const MapType::value_type&)>

to return by value, or change

boost::bind(&MapType::value_type::second, _1)

to

boost::bind<const MapType::mapped_type&>(&MapType::value_type::second, _1)

to return by reference.

boost::bind was changed to return by value because the old behavior suffered
from a similar reference-to-temporary problem with nested binds (that didn't
even produce a warning.)


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