Dereference shared_ptr of vector in range-based for loop

Question | Oct 1, 2019 | nextptr 

In general, the C++ range-based for loop has the format as shown below:

for(range_declaration : range_expression) {
 /* loop body*/

It is perfectly fine for range_expression to be something that results in a temporary. Take an example of that. The following loop is using a temporary and works as expected:

auto foo() { //returns by value
  return std::initializer_list<int>{1,2,3};

for(auto i : foo())  //OK
 std::cout << i;

But there is a saying, "sight is one of the most easily deceived senses." It is fine to use a range_expression that returns a temporary, but what happens if the range_expression has a temporary within it? Consider this seemingly innocuous code below:

/* returns a shared_ptr of vector by value */
auto getData() { //Requires C++14

 auto ptr = std::make_shared<std::vector<int>>(10);

 //range fill vector (0,1,2,3,4,5,6,7,8,9)
 std::iota(ptr->begin(), ptr->end(), 0); 
 return ptr;

//Use getData somewhere else in range loop
for(auto i : *getData()) // Is it OK??
 std::cout << i; 

Bear in mind that, the getData() is returning an std::shared_ptr by value, not a std::vector by value. Therefore, the range-based for loop above is iterating over a temporary std::vector returned by dereferencing a temporary std::shared_ptr.

Select from below what would be the output of the above (check Explanations for details):