12

I need to write a class whose constructor takes a constant reference to a object and stores it locally.

In order to avoid most common mistakes I can foresee, I'd like to only accept references to non-temporary (ie: references to lvalues).

How can I write a function that takes constant references to non-temporary only?


Of course even a non-temporary could go out of scope and thus break my class behavior, but I believe that by disallowing temporary references I will avoid most mistakes.

peoro
  • 25,562
  • 20
  • 98
  • 150
  • Why do you think you avoid most mistakes like this? – Martin York Dec 28 '10 at 00:12
  • Well, the object whose reference I need to pass doesn't require to be used after it's instantiated (ie: I just instantiate the object and pass it, thus due to my code style I wouldn't instantiate it on the stack). If I forget that other class' constructor need a _permanent_ value, seeing the temporary rejected (ie: compiled time error) that will remember me, I hope. – peoro Dec 28 '10 at 14:52

1 Answers1

19

If you are going to store a reference and need to use it after the constructor has completed, it's probably best for the constructor to take a pointer:

struct C {
    C(const X* p) : p_(p) { }

    const X* p_;
};

This way, it's pretty much guaranteed that you won't have a pointer to a temporary (unless X does something really dumb, like overloading the unary & to return this).

If the constructor takes a pointer, it's also clearer to users of the class that they need to pay attention to the lifetime of the X object they pass to the constructor.

James McNellis
  • 348,265
  • 75
  • 913
  • 977
  • 2
    Yeah, agree, clean and smart solution! I'll also assert that `p` is not null, and will store it as a reference. – peoro Dec 28 '10 at 14:53
  • Agree, OP should learn that pointers are better! Only use references when you absolutely have to (eg in copy constructors). – Yttrill Dec 28 '10 at 23:23
  • 1
    @Yttrill: No, that's not at all what I'm trying to say. References are extraordinarily useful and should be preferred when one has the choice between using either references or pointers. There are, however, certain circumstances when references either won't work at all (e.g. a reference can't be a member of an assignable class) or don't work well (e.g. the OP's scenario). – James McNellis Dec 28 '10 at 23:27
  • @JamesMcNellis: Note you can update this answer now to go back to using reference, by providing a template `T&&` constructor and static asserting inside that `T` is a reference type. – GManNickG Mar 17 '13 at 18:53
  • 2
    @GManNickG: As a matter of convention, I find it preferable to use a pointer (and not a reference) for a parameter if the callee requires that the lifetime of the object extends beyond the duration of the call. If the parameter is a reference, it is far too easy to call the function without thinking about lifetime management. If the parameter is a pointer, it's a signal that you need to investigate the lifetime constraints. – James McNellis Mar 18 '13 at 16:58
  • 1
    6 years later :), but can I have example how one can use this? is `p` a dynamically allocated object? – Nick Feb 26 '16 at 20:58