Вдохновленный из другой темы , я написал этот код, который имитирует блок finally
:
#include <cassert>
#include <iostream>
struct base { virtual ~base(){} };
template<typename TLambda>
struct exec : base
{
TLambda lambda;
exec(TLambda l) : lambda(l){}
~exec() { lambda(); }
};
class lambda{
base *pbase;
public:
template<typename TLambda>
lambda(TLambda l): pbase(new exec<TLambda>(l)){}
~lambda() { delete pbase; }
};
class A{
int a;
public:
void start(){
int a=1;
lambda finally = [&]{a=2; std::cout<<"finally executed";};
try{
assert(a==1);
//do stuff
}
catch(int){
//do stuff
}
}
};
int main() {
A a;
a.start();
}
Вывод ( ideone ):
finally executed
@ Йоханнес, похоже, считает, что это не совсем правильно, и заметил, что :
Может произойти сбой, если компилятор не исключит временное вКопировать инициализацию, потому что затем он удаляет дважды с одним и тем же значением указателя
Я хотел бы знать, как именно.Помогите мне разобраться в проблеме: -)
РЕДАКТИРОВАТЬ:
Проблема устранена как:
class lambda{
base *pbase;
public:
template<typename TLambda>
lambda(TLambda l): pbase(new exec<TLambda>(l)){}
~lambda() { delete pbase; }
lambda(const lambda&)= delete; //disable copy ctor
lambda& operator=(const lambda&)= delete; //disable copy assignment
};
А затем использовать его как:
//direct initialization, no copy-initialization
lambda finally([&]{a=2; std::cout << "finally executed" << std::endl; });
Полный код: http://www.ideone.com/hsX0X