Я пытаюсь имитировать наконец подобный эффект. Поэтому я подумал, что должен провести быстрый грязный тест.
Идея заключалась в том, чтобы использовать Most Important const , чтобы остановить разрушение и поместить блок finally в лямбду. Однако, очевидно, я сделал что-то не так, и он был вызван в конце MyFinally (). Как мне решить эту проблему?
#include
template
class D{
T fn;
public:
D(T v):fn(v){}
~D(){fn();}
};
template
const D& MyFinally(T t) { return D(t); }
int d;
class A{
int a;
public:
void start(){
int a=1;
auto v = MyFinally([&]{a=2;});
try{
assert(a==1);
//do stuff
}
catch(int){
//do stuff
}
}
};
int main() {
A a;
a.start();
}
Мой код решения (Примечание: у вас не может быть два, наконец, в одном блоке. Как и ожидалось. Но все равно немного грязно)
#include
template
class D{
T fn; bool exec;
public:
D(T v):fn(v),exec(true){}
//D(D const&)=delete //VS doesnt support this yet and i didnt feel like writing virtual=0
D(D &&d):fn(move(d.fn)), exec(d.exec) {
d.exec = false;
}
~D(){if(exec) fn();}
};
template
D MyFinally(T t) { return D(t); }
#define FINALLY(v) auto OnlyOneFinallyPlz = MyFinally(v)
int d;
class A{
public:
int a;
void start(){
a=1;
//auto v = MyFinally([&]{a=2;});
FINALLY([&]{a=2;});
try{
assert(a==1);
//do stuff
}
catch(int){
FINALLY([&]{a=3;}); //ok, inside another scope
try{
assert(a==1);
//do other stuff
}
catch(int){
//do other stuff
}
}
}
};
void main() {
A a;
a.start();
assert(a.a==2);
}
Достаточно забавно, если вы удалите & в MyFinally в исходный код работает -_-.