Subject: [Boost-bugs] [Boost C++ Libraries] #7630: Range adaptors do not play nicely with range-based for loops
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2012-11-02 18:37:22
#7630: Range adaptors do not play nicely with range-based for loops
-------------------------------+--------------------------------------------
Reporter: gromer@⦠| Owner: neilgroves
Type: Bugs | Status: new
Milestone: To Be Determined | Component: range
Version: Boost 1.51.0 | Severity: Problem
Keywords: |
-------------------------------+--------------------------------------------
Consider the following C++11 code, adapted from the Range documentation:
{{{
std::vector<int> vec;
for (int val : vec | boost::adaptors::reversed
| boost::adaptors::uniqued) {
// Do stuff with val
}
}}}
The behavior of this natural-seeming code is actually undefined, due to a
dangling reference: per the C++ standard, it is equivalent to
{{{
{
auto && __range = (vec | boost::adaptors::reversed
| boost::adaptors::uniqued);
for ( auto __begin = __range.begin(),
__end = __range.end();
__begin != __end;
++__begin ) {
int val = *__begin;
// Do stuff with val
}
}
}}}
The problem is that the value returned by the subexpression `vec |
boost::adaptors::reversed` is a temporary, so its lifetime ends at the end
of the statement containing it, namely the declaration of `__range`. Thus,
`__range` is left holding a dangling reference to the range it's adapting.
The fix is for each range adaptor to use an rvalue-reference overload to
detect whether the input range is a temporary, and if so, move it into the
adaptor (i.e. with `std::move`) in order to extend its lifetime.
-- Ticket URL: <https://svn.boost.org/trac/boost/ticket/7630> Boost C++ Libraries <http://www.boost.org/> Boost provides free peer-reviewed portable C++ source libraries.
This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:11 UTC