Reference to temporary

This article will discuss references to temporary objects – a mechanism with a few subtleties.

Suppose we have defined a function that returns a temporary object:

std::string date (); // returns current date

As we all know, the object returned by this function is a temporary string, which lives for the duration of the line it has been defined in (the line invoking the call to date()). Therefore, the following code is illegal:

std::string &ref = date();
std::cout << ref; // dangling reference to temp

Until now it’s all easy and trivial. What if we use a const reference:

const std::string &ref = date();
std::cout << ref; // ok!

This use is perfectly fine and legitimate. If you read the C++ spec you will discover that defining a const reference to a temporary object extends its lifetime! This is absolutely great.. And there’s more.

If we extend the object’s lifetime by using the aforementioned const reference, we could ask ourselves the following question: which destructor will be called when the const reference goes out of scope? The answer to this question is: the destructor that would be called on that object normally is just delayed, and will be invoked when needed. This is very interesting.. It means that the correct destructor will be called, without virtual dispatching being involved at all!

Let me introduce an example to illustrate the situation:

struct A {
    ~A () {} // not virtual
};

struct B : A {
    ~B () {}
};

B func (); // returns a B object

int main () {
    const A& ref = func(); // reference to A
    // ... code using ref ...
} // B's destructor is invoked!

This is probably the only example of what seems to be virtual dispatching, without anything being actually virtual (in the example there isn’t even a vtable), in C++.

In my opinion this is a great interview question. I would not necessarily expect interviewees to know this, but there’s a lot to be learned from their thinking process when lead to the answer.

I bumped into this issue at Herb Sutter’s GotW.

2 thoughts on “Reference to temporary

  1. It’s not virtual dispatching, since its temp object being destructed. And type of that temp object is known at compilation time. Think of it as if it was something in the lines of { B tmp = func(); const & A = tmp; }, only with the move semantics. Otherwise very good article.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>