Почему вызывается dtor (с использованием анонимной / лямбда-функции)

Я пытаюсь имитировать наконец подобный эффект. Поэтому я подумал, что должен провести быстрый грязный тест.

Идея заключалась в том, чтобы использовать 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 в исходный код работает -_-.

5
задан Johannes Schaub - litb 2 October 2011 в 10:30
поделиться