4

Consider

std::vector<abc> fun() { return a;}
..
..

for( auto itr = fun().begin(); itr< fun().end(); ++itr) //A
 {
  ..
 }
for( auto & itr : fun()) //B
 {
 }

Are both loops here are unsafe? (iterators not being compatible?)

user6386155
  • 825
  • 7
  • 17
  • The 2nd version can't work. Both calls to `fun()` returns a different `std::vector`. You cannot compare iterators from different containers. – François Andrieux Jun 02 '17 at 17:59
  • the ranged for you wrote is using vs's extention, it should be const reference – Sopel Jun 02 '17 at 18:00
  • (I read this questions as you being aware the first variant is wrong.) – Baum mit Augen Jun 02 '17 at 18:00
  • @DanielSchepler It is 100% safe. You should reread the reference: http://en.cppreference.com/w/cpp/language/range-for – NathanOliver Jun 02 '17 at 18:07
  • @NathanOliver Oh right, I was confusing it with the case `boost::optional f(); ... for (auto c : *(f())) { ... }` which isn't safe because `boost::optional::operator*() &&` returns a `T&&` but the `f()` temporary then isn't lifetime-extended. Sorry for the confusion. – Daniel Schepler Jun 02 '17 at 18:13

1 Answers1

3

This is undefined behavior.

for( auto itr = fun().begin(); itr< fun().end(); ++itr) //A
{
    ..
}

The std::vector from fun().begin() will be a completely different std::vector than that returned from fun().end().

Therefore the comparison itr < fun().end() is comparing iterators from two different containers, which is undefined behavior.

The second version (B) will work fine as described in this post.

for (auto & itr : fun()) //B
{
}
Cory Kramer
  • 114,268
  • 16
  • 167
  • 218