Stavo leggendo sulla dichiarazione defer della lingua. Ti consente di specificare un'azione da eseguire quando una funzione è terminata. Ad esempio, se si dispone di un puntatore o risorsa di file, invece di scrivere liberamente/eliminare con ogni possibile percorso di ritorno, è sufficiente specificare la funzione di rinvio una volta."defer" in stile golan in C++
Sembra che un analogo potrebbe arrivare a C++ (What is standard defer/finalizer implementation in C++?, Will there be standardization of scope guard/scope exit idioms?) Fino ad allora, c'è qualcosa di imprevisto nel farlo con un oggetto il cui distruttore effettua una richiamata? Sembra che sia lo destructor order for local variables is sane e che gestisca bene anche le eccezioni, anche se forse non sta uscendo sui segnali.
Ecco un'implementazione di esempio ... c'è qualcosa di preoccupante a riguardo?
#include <iostream>
#include <functional>
using namespace std;
class FrameExitTask {
std::function<void()> func_;
public:
FrameExitTask(std::function<void()> func) :
func_(func) {
}
~FrameExitTask() {
func_();
}
FrameExitTask& operator=(const FrameExitTask&) = delete;
FrameExitTask(const FrameExitTask&) = delete;
};
int main() {
FrameExitTask outer_task([](){cout << "world!";});
FrameExitTask inner_task([](){cout << "Hello, ";});
if (1+1 == 2)
return -1;
FrameExitTask skipped_task([](){cout << "Blam";});
}
uscita: Hello, world!
Questo potrebbe essere più appropriato per [CodeReview] (http://codereview.stackexchange.com). Nota che ci sono già molte implementazioni di questa classe simile a ScopeGuard, quindi perché reinventare la ruota? Alcune implementazioni che conosco hanno vari vantaggi o strumenti specializzati che preferirei alla tua versione (ad esempio, nessun tipo di cancellazione). – dyp
Il problema con questo è che ogni classe dovrebbe già fare ciò che si sta facendo nel proprio distruttore, quindi i casi d'uso in C++ sono molto più rari che in Go. Se stai cercando implementazioni esistenti, controlla boost.ScopeExit. La follia di Facebook ne ha una anche io penso. – inf
Probabilmente stai meglio contrassegnando il distruttore "noexcept". Se la funzione che usi 'FrameExitTask' nei ritorni normalmente, probabilmente un'eccezione dal tuo handler finale funzionerà. Se la funzione termina a causa di qualche altra eccezione, una seconda eccezione dal gestore causerà problemi. –