Is it possible to determine whether an object is temporary inside a member function?

I implement a decorator pattern on immutable objects with an idiom pointer to an implementation. Basically my setup is as follows

struct Object : ObjectBase { void doSmth() override { impl->doSmth(); } // this is the function I'd like to implement Object decorateWith(std::unique_ptr<ObjectDecorator>&&); private: std::unique_ptr<ObjectBase> impl; }; struct ObjectDecorator : ObjectBase { void doSmth() override { // do some stuff impl->doSmth(); // do some more stuff } private: std::unique_ptr<ObjectBase> impl; }; 

Here, the decorateWith function should have a different behavior depending on whether the object it called is temporary or not. If it is called on a non-temporary object, it should return a new instance of the object, where I need to make a deep copy of the current object and save it in the decorator's unique_ptr, while the impl pointer of the new object itself points to the decorator. If, however, decorateWith is called temporarily, just create an ObjectDecorator and simply move the pointer-pointer of the current object to the impl pointer of the decorator and let the object point to the new decorator.

In order to impose that I need a way to determine from inside the call to decorate with whether the object is temporary or not, and then use the send tags based on the result of this check. Is it possible?

Best Xodion

EDIT: An example caller code might look like this:

  • decorateWith called on non-temporary

     int main() { Object x{}; // this call does not modify x so it can be reused later Object y = x.decorateWith{std::make_unique<ObjectDecorator>()}; y.doSmth(); // do some other stuff here // here, if I had moved the impl-unique_ptr in the decorateWith // call this would now segfault since I'd call nullptr->doSmth(); x.doSmth(); } 
  • decorateWith called temporary

     int main() { Object x = Object{}.decorateWith(std::make_unique<ObjectDecorator>()) .decorateWith(std::make_unique<ObjectDecorator>()) .decorateWith(std::make_unique<ObjectDecorator>()); // in this case it would be unneccessary to make a deep copy of all // previous instances so I'd like to only move the impl poiner every time x.doSmth() } 
+5
source share
3 answers

You may have ref-qualifiers for member functions. Copy example from en.cppreference.com

 #include <iostream> struct S { void f() & { std::cout << "lvalue\n"; } void f() &&{ std::cout << "rvalue\n"; } }; int main(){ S s; sf(); // prints "lvalue" std::move(s).f(); // prints "rvalue" S().f(); // prints "rvalue" } 

So in your situation you would like to have something like this

  Object decorateWith(std::unique_ptr<ObjectDecorator>&&) &; Object decorateWith(std::unique_ptr<ObjectDecorator>&&) &&; 
+12
source

You can use reference qualifiers to overload a member function, similar to how you would use const to overload for const and not const objects:

 Object decorateWith(std::unique_ptr<ObjectDecorator>&&) const& { // implementation if this is not a temporary } Object decorateWith(std::unique_ptr<ObjectDecorator>&&) && { // implementation if this IS a temporary } 
+4
source

Yes. If you implement the following two methods:

  Object decorateWith(std::unique_ptr<ObjectDecorator>&&) &; Object decorateWith(std::unique_ptr<ObjectDecorator>&&) &&; 

the second will be called if *this is the value of r.

+2
source

All Articles