Recentemente, mi sono imbattuto in un problema riguardante la progettazione della protezione per ambito. Una guardia di ambito richiama un oggetto funzione fornito (di solito esegue procedure di pulizia) all'uscita dall'ambito di inclusione. Il design attuale è il seguente:
#define HHXX_ON_SCOPE_EXIT_F(...) ...
#define HHXX_ON_SCOPE_EXIT(...) HHXX_ON_SCOPE_EXIT_F([&]() { __VA_ARGS__ })
HHXX_ON_SCOPE_EXIT_F(...)
esegue l'oggetto funzione come definito da __VA_ARGS__
all'uscita dall'ambito di chiusura. Ad esempio,
int i = 0;
{
HHXX_ON_SCOPE_EXIT_F([&]() {
assert(++i == 4);
});
HHXX_ON_SCOPE_EXIT_F([&]() {
assert(++i == 3);
});
HHXX_ON_SCOPE_EXIT(
assert(++i == 2);
);
HHXX_ON_SCOPE_EXIT(
assert(++i == 1);
);
}
assert(i == 4);
Anche l'implementazione è semplice:
#define HHXX_ON_SCOPE_EXIT_F(...) \
auto HHXX_UNIQUE_NAME(hhxx_scope_guard) = \
make_scope_guard(__VA_ARGS__)
#define HHXX_ON_SCOPE_EXIT(...) HHXX_ON_SCOPE_EXIT_F([&]() { __VA_ARGS__ })
template <typename F>
class scope_guard {
public:
explicit scope_guard(F f)
: f_(std::move(f)) {
// nop
}
~scope_guard() {
f_();
}
private:
F f_;
};
template <typename F>
auto make_scope_guard(F f) {
return scope_guard<F>(std::move(f));
}
Come puoi vedere, non fornisce un supporto integrato per un metodo per abbandonare la chiamata all'uscita dell'ambito. Fornire tale funzionalità, tuttavia, annulla la concisione e la semplicità del design attuale. Induce anche alcuni overhead delle prestazioni. Sostanzialmente, sono favorevole al mantenimento dell'attuale design e al rifiuto della proposta di funzionalità. Voglio ascoltare le opinioni di voi ragazzi, per essere sicuri di prendere una decisione giusta.