I'm trying to iterate over a temporary object in a range for loop. It looks like the object gets desctucted before the loop begins executing. Is this a standard compliant behaviour? I'm using gcc 4.8.
#include <iostream>
#include <vector>
#include <memory>
struct Test: std::vector<int> {
  Test(): std::vector<int>{1,2,3} {
    std::cout << __PRETTY_FUNCTION__ << '\n';
  }
  ~Test() {
    std::cout << __PRETTY_FUNCTION__ << '\n';
  }
};
std::shared_ptr<Test> func() {
  return std::shared_ptr<Test>(new Test);
}
int main() {
  for (const auto &obj: *func()) {
    std::cout << obj << '\n';
  }
}
The result is as follows:
Test::Test()
Test::~Test()
21770300
0
33
0
0
0
3
                Yes, the behavior is compliant.
Per paragraph 6.5.4/1 of the C++11 Standard:
For a range-based
forstatement of the formfor ( for-range-declaration : expression ) statementlet range-init be equivalent to the expression surrounded by parentheses
( expression )and for a range-based
forstatement of the formfor ( for-range-declaration : braced-init-list ) statementlet range-init be equivalent to the braced-init-list. In each case, a range-based for statement is equivalent to
{ auto && __range = range-init; for ( auto __begin = begin-expr, __end = end-expr; __begin != __end; ++__begin ) { for-range-declaration = *__begin; statement } }
In your case, the returned shared pointer is dereferenced, and the object it points to is bound to the __range reference. However, the shared pointer itself is not copied, nor is it bound to a reference that would prolong its lifetime. Therefore, it goes out of scope. Being the last shared pointer referencing the pointed object, the object gets destroyed too.
Things would have been different if you had returned your Test object by value, rather than returning a shared pointer:
Test func() {
  return Test();
}
int main() {
  for (const auto &obj: func()) {
    std::cout << obj << '\n';
  }
}
This way, the Test temporary returned by func() is bound to the  __range reference, and its lifetime is prolonged to match the lifetime of the reference. 
Here is a live example.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With