transform_iterator causing strange problems
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
I made a mistake in copying the code----"segs" and "vec" are actually the same thing. Just forgot to change it one place. So that's not the problem, just FYI.
----- Original Message -----
From: Lindley M French
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
(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
const_iterator; const_iterator begin() const { return boost::make_transform_iterator(currgroups.begin(),GroupSelector()); } const_iterator end() const { return boost::make_transform_iterator(currgroups.end(),GroupSelector()); } std::pair groups() const { const Group &grp = *(begin()); return std::make_pair(begin(),end()); } Where my GroupSelector class is defined as
struct GroupSelector { typedef const Group& result_type; const Group& operator()(const std::pair
&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?
AMDG 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
(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
const_iterator; <snip> Where my GroupSelector class is defined as
struct GroupSelector { typedef const Group& result_type; const Group& operator()(const std::pair
&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
Okay, that makes sense as a cause, anyway. I'm not clear on how to fix it. Does this mean that transform_iterator can't be used to convert a map iterator into a value or key iterator? I've done that before and it seemed to work, but that may have been a std::map rather than a boost::unordered_map.....or perhaps it was the fact that I was returning by value before.
If I have to return by value for this to be feasible, it's not worth it. I'll just go with the slightly messier interface.
----- Original Message -----
From: Steven Watanabe
AMDG
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
(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
const_iterator; <snip> Where my GroupSelector class is defined as
struct GroupSelector { typedef const Group& result_type; const Group& operator()(const std::pair
&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
Lindley M French wrote: 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
is pair * std::pair has a converting constructor. * Therefore, when transorm_iterator calls your function object, it creates a temporary std::pair which goes out of scope when operator* returns. In Christ, Steven Watanabe
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
Lindley M French wrote:
Okay, that makes sense as a cause, anyway. I'm not clear on how to fix it. Does this mean that transform_iterator can't be used to convert a map iterator into a value or key iterator? I've done that before and it seemed to work, but that may have been a std::map rather than a boost::unordered_map.....or perhaps it was the fact that I was returning by value before.
If I have to return by value for this to be feasible, it's not worth it. I'll just go with the slightly messier interface.
----- Original Message ----- From: Steven Watanabe
Date: Tuesday, May 26, 2009 7:22 pm Subject: Re: [Boost-users] transform_iterator causing strange problems AMDG
Lindley M French wrote:
Please do not top post: http://www.boost.org/community/policy.html#quoting Thank you -- ---------------------------------- Michael Caisse Object Modeling Designs www.objectmodelingdesigns.com
AMDG Lindley M French wrote:
Okay, that makes sense as a cause, anyway. I'm not clear on how to fix it. Does this mean that transform_iterator can't be used to convert a map iterator into a value or key iterator? I've done that before and it seemed to work, but that may have been a std::map rather than a boost::unordered_map.....or perhaps it was the fact that I was returning by value before.
If I have to return by value for this to be feasible, it's not worth it. I'll just go with the slightly messier interface.
If you change the signature of operator() to take exactly the type that it is given, then there will be no implicit conversion and the behavior will be what you expect. In Christ, Steven Watanabe
Lindley M French wrote:
Okay, that makes sense as a cause, anyway. I'm not clear on how to fix it.
Well, given the cause is temporaries due to implicit conversions, just
don't make those implicit conversions.
just change
const Group& operator()(const std::pair
Mathias Gaunard wrote:
Lindley M French wrote:
Okay, that makes sense as a cause, anyway. I'm not clear on how to fix it.
Well, given the cause is temporaries due to implicit conversions, just don't make those implicit conversions.
just change const Group& operator()(const std::pair
&p) const to const Group& operator()(const std::pair
&p) const
The fact that the value of a map iterator does not exactly resemble the declaration of the map itself (implicit 'const' on the key) has bitten me more often than I care to admit. I've been trying to cultivate the habit of always using my_map_typedef::value_type whenever the std::pair in question comes from a map. So: const Group& operator()(const OP_map_typedef::value_type& p) const
Ah! That does make sense. Okay, I'll do that.
----- Original Message -----
From: Nat Goodspeed
Mathias Gaunard wrote:
Lindley M French wrote:
Okay, that makes sense as a cause, anyway. I'm not clear on how to fix it.
Well, given the cause is temporaries due to implicit conversions, just don't make those implicit conversions.
just change const Group& operator()(const std::pair
&p) const to const Group& operator()(const std::pair
&p) const The fact that the value of a map iterator does not exactly resemble the declaration of the map itself (implicit 'const' on the key) has bitten me more often than I care to admit. I've been trying to cultivate the habit of always using my_map_typedef::value_type whenever the std::pair in question comes from a map. So:
const Group& operator()(const OP_map_typedef::value_type& p) const _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
participants (5)
-
Lindley M French
-
Mathias Gaunard
-
Michael Caisse
-
Nat Goodspeed
-
Steven Watanabe