Boost logo

Boost Users :

Subject: Re: [Boost-users] transform_iterator causing strange problems
From: Steven Watanabe (watanabesj_at_[hidden])
Date: 2009-05-26 19:22:23


Lindley M French wrote:
> I'm not sure if this is the fault of transform_iterator----I really don't see how it could be----but I'm really confused here.
> I've got an unordered_map<GroupID, Group> (typedefed to GroupMap) in my class. The specifics of those types don't matter except that GroupID is an integral type, and Group contains a std::vector vec.
> I'm trying to use a transform_iterator so that my class may be viewed as a group container:
> typedef boost::transform_iterator<GroupSelector, GroupMap::const_iterator> const_iterator;
> <snip>
> Where my GroupSelector class is defined as
> struct GroupSelector
> {
> typedef const Group& result_type;
> const Group& operator()(const std::pair<GroupID, Group> &p) const
> {
> std::cout << p.second.vec.size() << " " << &p.second << std::endl;
> return p.second;
> }
> };
> Note the output statement. Now, the usage in my main function is
> for (tie(iter,end) = final.groups(); iter != end; ++iter)
> {
> const Group& grp = *iter;
> cerr << &grp << endl;
> cerr << grp.segs.size() << endl;
> ...
> My output is
> 10 0012F50C
> 10 0012F65C
> 0012F65C
> 1243176
> which is strange for two reasons. The first line comes from GroupSelector when I dereference begin() in the groups() function. The second comes from GroupSelector when I dereference iter in main. As these should both correspond to the same iterator, I can't understand why the address of the returned Group reference is different.
> The 3rd and 4th lines are outputted in main. Here's the second confusion: The address for the Group object is the same as in the most recent GroupSelector output, yet now the size of the vector within the Group comes out wrong. HUH?

* The value_type of unordered_map<GroupID, Group>
  is pair<const GroupID, Group>
* std::pair has a converting constructor.
* Therefore, when transorm_iterator calls your function object,
    it creates a temporary std::pair<GroupID, Group> which
    goes out of scope when operator* returns.

In Christ,
Steven Watanabe

Boost-users list run by williamkempf at, kalb at, bjorn.karlsson at, gregod at, wekempf at