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
for
statement of the formfor ( for-range-declaration : expression ) statement
let range-init be equivalent to the expression surrounded by parentheses
( expression )
and for a range-based
for
statement of the formfor ( for-range-declaration : braced-init-list ) statement
let 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