5

I've come across a situation where being able to chain a method call to a temporary variable would be really helpful:

draw(Quad(0, 0, 1, 1).rotate(90));  // <-- .rotate() returns a Quad reference

struct Quad{
    Quad(float x, float y, float width, float height){...}
    Quad & rotate(float degrees){
        ...
        return *this;
    }
}

However, I'm unsure if the temporary variable will remain alive long enough for the draw() function to use it. Is this safe to do?

Anne Quinn
  • 12,609
  • 8
  • 54
  • 101

2 Answers2

12

This particular use is safe. A temporary lasts until the end of the full-expression that creates it; here, the full-expression is the whole statement, including the call to draw.

In general, this pattern could be dangerous. The following gives undefined behaviour:

Quad & rotated = Quad(0, 0, 1, 1).rotate(90);
draw(rotated);

In my opinion, I'd prefer the type to be immutable; rather than calling a function to modify an existing object, call a const function to return a new object, leaving the existing object intact.

Unless its bound directly to a reference, which extends its lifetime to match the reference. This doesn't apply here, since it's not bound directly.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
  • 1
    I like your answer better than mine, since you managed to actually give a concrete suggestion on how to write a better class, something I couldn't quite manage. Let's go with yours. :) –  Feb 18 '15 at 11:36
  • I agree. But isn't the same pattern the convention with assignment operators? If this pattern is dangerous, does that mean assignment operators are dangerous for the same reason? – Chris Drew Feb 18 '15 at 11:58
  • 1
    @ChrisDrew: Yes, conventional class assignment operators also return references, so something weird like `T & t = (T() = x);` would give you a dangling reference. But sensible code is unlikely to assign to a temporary, or to bind the result of assignment to a reference, and there's no danger unless you do both these things. – Mike Seymour Feb 18 '15 at 12:02
6

Yes, the temporary Quad is destroyed at the end of the full expression (trailing ;). So it's still alive when you call rotate on it, and still alive when you call draw with it as a parameter.

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625