Reputation: 1498
I'm wondering if the following is valid:
#include <iostream>
#include <vector>
std::vector<int>& getVec()
{
static std::vector<int> vec{1, 2, 3, 4, 5};
return vec;
}
int main()
{
for (const auto& i : getVec())
{
std::cout << "i = " << i << std::endl;
}
return 0;
}
Basically I'm unsure about the lifetime of the temporary from getVec()
. I've looked at both this post and this one, but am in a bit of a different situation as my function returns a reference to static
data. Specifically, I'm wondering if scenario violates the following exception in the stated rule:
- A temporary bound to a reference parameter in a function call [...]
or if this is indeed safe code. I think it is safe, but just wanted to be sure.
Upvotes: 1
Views: 97
Reputation: 30579
Yes, this is fully valid and well-defined.
The range-based for loop in your question is defined to be equivilent to the following, for imaginary variables range
, begin
, and end
:
auto&& range = getVec();
auto begin = std::begin(range);
auto end = std::end(range);
for (; begin != end; ++begin)
{
const auto& i = *begin;
{
std::cout << "i = " << i << std::endl;
}
}
After reference collapsing rules are applied, the type of range
becomes std::vector<int>&
. That means no temporaries are ever created. The loop iterates over the static vector defined in getVec
.
If getVec
instead returned by value, the type of range
would be std::vector<int>&&
, and lifetime extension would be applied. That would extend the lifetime of the temporary object to that of the reference, and everything would still be totally valid.
Upvotes: 2