2

aka. how do I prevent a const& parameter from accidentally binding to a temporary?

We have a class that essentially looks like this:

template<typename T>
struct Observer {
  const T* target;

  void observe(const T& x) {
     target = &x;
  }
};

That is, these objects will "hold on" to the const-ref they get passed.

We had a bug where the observe function accidentally got passed a temporary object - something that can never be valid for this case.

What options do we have to prevent accidentally binding to a temporary?

Changing the signature to (const T* px) would work technically (taking the address of a temporary is a compiler warning=error here) it is not very attractive for other reasons.

Side note: Yeah, this will always have potential lifetime management issues, but so far the real thing worked pretty well because of its limited usage pattern - but passing temporaries accidentally has been observed in practice, so we want to possibly address that first.

Martin Ba
  • 37,187
  • 33
  • 183
  • 337

1 Answers1

5

You can add a rvalue reference overload, and delete it:

void observe(const T&& x) = delete;

Now a compile error will be issued if someone tries to pass a temporary.

Brian Bi
  • 111,498
  • 10
  • 176
  • 312
  • Could anyone explain how will that work? Does `T&& x` mean that `x` is a reference of a reference? Otherwise, what's the difference between void `observe(const T& x)` and `void observe(const T&& x)`? – Ahmed Aboumalek Dec 01 '16 at 22:46
  • 1
    @Angelo It is an rvalue reference. – Brian Bi Dec 01 '16 at 22:50
  • What about the non-const `(T&& x) ` overload - is that needed in any way and how does it relate to the overload set? – Martin Ba Dec 02 '16 at 10:25
  • @MartinBa It is not needed because a non-const rvalue will still prefer the `const T&&` overload. – Brian Bi Dec 02 '16 at 20:02