I'm implementing a decorator pattern on immutable objects with the pointer-to-implementation idiom. Basically my setup looks like this
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 is supposed to have different behavior depending on the whether the object it is callen on is a temporary or not. If it is called on a non-temporary object, it is supposed to return a new Object instance where I have to make a deep copy of the current Object and store it in the unique_ptr of the decorator while the impl pointer of the new Object itself is pointing to the decorator. If, however, decorateWith is called on a temporary, it suffices to create a ObjectDecorator and just move the impl-pointer of the current object into the impl pointer of the decorator and let the object point to the new decorator.
In order to impelement that I need a way to determine from within the call to decorateWith whether the object is a temporary or not and then use tag-dispatch based on the result of that check. Is that possible?
Best Xodion
EDIT: Sample caller code could look like this:
decorateWith is called on a 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 is called on a 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() }
Object
decorateWith
is called from is temporary, or if the argument todecorateWith
is temporary? – Bacteroid