Ситуация в первом приближении следующая: есть функция, которая ведет подсчет и в конце свой работы должна записать результат в некую глобальную переменную. В ходе работы функции могут возникать исключения, но при этом уже посчитанный результат все равно должен быть помещен в глобальную переменную.
В голову приходят два пути решения.
1. Родить вот такого уродца:
class myint {
private:
int value;
public:
myint(int i) : value(i) {};
~myint() { Global = value; };
const myint operator++(int) { int oldvalue = value; value++; return myint(oldvalue); }
//Ну у меня только счетчик, а вот если другие понадобятся, перегружаем и их
} Result = 0;
Ушли за область видимости, сработал деструктор и выполнил задачу. Но уж слишком городить приходиться.
2. В С++11 можно сделать веселей:
std::unique_ptr<int, void(*)(int*)> Result(new int, [](int* p) { Global = *p; delete p; });
*Result = 0;
Все здорово и красиво, но вот теперь придется постоянно разименовывать (всегда ставить *), что немного смущает.
Быть может есть еще пути решения, например можем (сам понимаю что чушь, ну а вдруг) хранить в unique_ptr не ссылку а само значение?
Это бы решило мою задачу.
Здравствуйте, dosik, Вы писали:
D>D>std::unique_ptr<int, void(*)(int*)> Result(new int, [](int* p) { Global = *p; delete p; });
D>*Result = 0;
D>
Сорри, сразу не допер, а ларчик просто открывался:
std::unique_ptr<int, void(*)(int*)> ptrResult(new int, [](int* p) { Global = *p; delete p; });
int & Result = *ptrResult;
Result = 0; // И все как обычно!!!
Здравствуйте, dosik, Вы писали:
D>Быть может есть еще пути решения, например можем (сам понимаю что чушь, ну а вдруг) хранить в unique_ptr не ссылку а само значение?
То, что Вы пытаетесь реализовать, называется
Scope Guard. Использовать для этого
std::unique_ptr можно, но не совсем корректно с идеологической т.з. (поскольку у него несколько иное предназначение).
Для C++03- есть
Boost.ScopeExit.
В C++11+ вместо того, чтобы каждый раз "рожать уродца", можно один раз реализовать что-то в духе
std::scoped_function (
N3677. A Proposal to Add additional RAII Wrappers to the Standard Library) или
std::scope_exit (
N4189. Generic Scope Guard and RAII Wrapper for the Standard Library) и спокойно дожидаться появления этого в стандартной библиотеке. Второй вариант ведет свою родословную от ScopeGuard11 из презентации
Systematic Error Handling in C++ Александреску, как я понимаю.