Yes, it is wrong thing to do indeed. When you call:
return v;
temporary copy of object v
is being created and
const int &myIntRef = f()[0];
initializes your reference with the first element of this temporary copy. After this line, the temporary copy no longer exists, meaning that myIntRef
is an invalid reference, using of which produces undefined behavior.
What you should do is:
std::vector<int> myVector = f();
const int &myIntRef = myVector[0];
std::cout << myIntRef << std::endl;
which (thanks to copy elision) uses an assignment operator to initialize myVector
object by using v
without copy of v
being created. In this case the lifetime of your reference is equal to the lifetime of myVector
object, making it perfectly valid code.
And to your second question:
"Also, is the following a valid fix, or is it still a bug?"
const int myIntCopy = f()[0]; // copy, not a reference
Yes, this is another possible solution. f()[0]
will access the first element of the temporary copy and use its value to initialize myIntCopy
variable. It is guaranteed that the copy of v
returned by f()
exists at least until the whole expression is executed, see C++03 Standard 12.2 Temporary objects §3:
Temporary objects are destroyed as the last step in evaluating the full-expression (1.9) that (lexically) contains the point where they were created.