Sto implementando un modello decoratore su oggetti immutabili con l'idioma puntatore-implementazione. Fondamentalmente la mia configurazione è simile al seguenteÈ possibile rilevare se l'oggetto è temporaneo all'interno della funzione membro?
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;
};
Qui, la funzione decorateWith si suppone di avere un comportamento diverso a seconda del fatto che l'oggetto è Callen su un temporaneo o meno. Se viene richiamato su un oggetto non temporaneo, si suppone che restituisca una nuova istanza Object dove devo fare una copia profonda dell'oggetto corrente e memorizzarla nel unique_ptr del decoratore mentre il puntatore impl del nuovo oggetto stesso sta indicando il decoratore. Se, tuttavia, decorareWith viene chiamato su un temporaneo, è sufficiente creare un ObjectDecorator e spostare semplicemente il puntatore impl dell'oggetto corrente nel puntatore impl dell'arredatore e lasciare che l'oggetto punti al nuovo decoratore.
Per impelare ho bisogno di un modo per determinare dall'interno della chiamata di decorWith se l'oggetto è temporaneo o meno e quindi utilizzare tag-dispatch in base al risultato di tale controllo. È possibile?
Miglior Xodion
EDIT: codice chiamante di esempio potrebbe essere la seguente:
decorateWith viene chiamato su un non-temporanea
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 è chiamato a titolo temporaneo
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() }
La spiegazione potrebbe essere meglio sottoposta a backup con codice di chiamata di esempio. – kfsone
Stai chiedendo di determinare se 'Object'' decorWith' è chiamato da è temporaneo, o se l'argomento di 'decorWith' è temporaneo? – md5i
Voglio spostarmi condizionatamente solo quando l'oggetto su cui decorareWith viene chiamato è temporaneo e crea una copia profonda altrimenti, quindi si tratta di verificare se un oggetto è temporaneo. Come dimostrano le risposte di seguito, non è necessario alcun tipo di tratto di tipo poiché è possibile sovraccaricare l'uso di qualificatori di riferimento. – Corristo