Ho una funzione che opera su una grande porzione di dati passati come argomento sink. Il mio tipo BigData
è già C++ 11-aware e viene fornito con il costruttore mossa completamente funzionale e spostare le implementazioni di assegnazione, così posso andare via senza dover copiare il dannato:Argomenti di sink e spostamento della semantica per le funzioni che possono fallire (sicurezza delle eccezioni)
Result processBigData(BigData);
[...]
BigData b = retrieveData();
Result r = processBigData(std::move(b));
Questo tutto funziona perfettamente bene. Tuttavia, la mia funzione di elaborazione potrebbe non riuscire occasionalmente in fase di runtime con conseguente eccezione. Questo non è davvero un problema, dato che posso solo risolvere roba e riprovare:
BigData b = retrieveData();
Result r;
try {
r = processBigData(std::move(b));
} catch(std::runtime_error&) {
r = fixEnvironmnentAndTryAgain(b);
// wait, something isn't right here...
}
Naturalmente, questo non funzionerà.
Poiché I si è spostato i miei dati nella funzione di elaborazione, al momento dell'arrivo nel gestore di eccezioni, b
non sarà più utilizzabile.
Questo minaccia di ridurre drasticamente il mio entusiasmo per il passaggio di argomenti inaffondabili.
Quindi, ecco la domanda: come affrontare una situazione come questa nel moderno codice C++? Come recuperare l'accesso ai dati precedentemente spostati in una funzione che non è riuscita a eseguire?
È possibile modificare l'implementazione e le interfacce per entrambi BigData
e processBigData
come si desidera. La soluzione finale dovrebbe tuttavia cercare di minimizzare gli inconvenienti rispetto al codice originale per quanto riguarda l'efficienza e l'usabilità.
Domanda importante, il risultato contiene le risorse spostate di b o si basa solo su di esso? – IdeaHat
@MadScienceDreams Il 'Result' è calcolato da' b', esso _non_ contiene un riferimento a, o una copia dell'originale 'b'. – ComicSansMS
@ComicSansMS Ma contiene i contenuti spostati (al contrario di quelli copiati)? – Potatoswatter