Is it safe to pass a temporary object to a function that accepts by reference in C++?
I have a function std::shared_ptr<int> create_ptr(int val) that creates a shared pointer and a function void print(int& val) which accepts by reference. I want to pass a shared pointer directly to the function as follows: print(*create_ptr(123)). Is this safe to do and normal in terms of C++ rules?
I assume it is normal because the object is allocated and not deleted until the function is finished. To illustrate, the following code is compiled well:
std::shared_ptr<int> create_ptr(int val)
{
return std::make_shared<int>(val);
}
void print(int& val)
{
std::cout << "*** Print value: " << val << '\n';
}
int main()
{
print(*create_ptr(123)); // Why does it work?
}
I am still confused why this works. How would you explain it?
Yes, it is safe to pass a temporary object to a function that accepts a reference in C++. In the code you provided, print(*create_ptr(123)) is valid and works as expected.
The reason it works is because the temporary shared_ptr<int> returned by create_ptr is bound to a const reference in the print function. The lifetime of the temporary object is extended to the lifetime of the reference it is bound to. This is a language feature in C++ called “lifetime extension” or “temporary materialization”.
In this case, the temporary shared_ptr<int> is dereferenced with *create_ptr(123), which returns a reference to the int value inside the shared_ptr. This reference is then passed to the print function, which accepts a non-const reference. However, since the temporary object’s lifetime is extended, it remains valid throughout the execution of the print function.
So, in summary, it is safe and normal to pass a temporary object to a function that accepts by reference in C++, as long as the temporary object’s lifetime is extended to cover the entire duration of the function call.