3 ms·
> Safe Handling of Aliases Er, why wouldn't you just use automatic storage duration? That would look even simpler than the Vale implementation and have the sam
by sagarm 6y ago
> Safe Handling of Aliases
Er, why wouldn't you just use automatic storage duration? That would look even simpler than the Vale implementation and have the same benefits:
class BigClass {
A a;
B b{&a};
C c{&a};
D d{&a, &c};
};
You could of course explicitly write the constructor if you choose.
> Destructor Parameters
This can be done in C++: both unique and shared ptrs can take a deleter instance. So for the rollback example:
std::unique_ptr<Transaction, Transaction::RollbackWithMode> tx(
new Transaction(), Transaction::RollbackWithMode(mode));
But my question is -- why? At this point you are losing one of the main benefits of RAII IMO: scheduling cleanup work right next to initialization work, allowing you to assume it is taken care of as you read the rest of the function:
Transaction tx(conn, Transaction::ROLLBACK_MODE_TUMBLE);
...
if (ok) { tx.commit(); }
return;
Similarly with the Future example -- IMO this is far clearer:
void Producer(Future<T> future) {
auto auto_reject = AutoRun([&] {
if (!future.ready()) future.reject();
});
...code, including potentially many branches....
}
where AutoRun is something simple like
template <typename Functor>
auto AutoRun(Functor f) {
class AutoRunner {
public:
AutoRunner(Functor f) : f_(f) {}
~AutoRunner() { f_(); }
private:
Functor f_;
};
return AutoRunner(f);
}
- verdagon 6y agoGreat question! We could also use a deleter, set up when we create the object, but thats often too early to know what parameters to pass into the destructor. In some cases, you do know the destruction parameters up-front, and there I would agree that a deleter is great. Sometimes you can't know the parameters up front, so can't easily get them into the deleter when you initialize. The call-once std::function and the future are good examples: These both take parameters which you might not know until later on. If you already know the values of a future when you're creating it, it probably wouldn't be a future. future.~resolve(resultOfSomeAsynchronousCalculation);