Значение вместо указателя std::unique_ptr или очередная попытка try...finally
От: dosik Россия www.dosik.ru
Дата: 11.09.15 13:41
Оценка:
Ситуация в первом приближении следующая: есть функция, которая ведет подсчет и в конце свой работы должна записать результат в некую глобальную переменную. В ходе работы функции могут возникать исключения, но при этом уже посчитанный результат все равно должен быть помещен в глобальную переменную.

В голову приходят два пути решения.
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 не ссылку а само значение?
Это бы решило мою задачу.
Re: Значение вместо указателя std::unique_ptr или очередная попытка try...finall
От: dosik Россия www.dosik.ru
Дата: 11.09.15 13:50
Оценка: :)
Здравствуйте, 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; // И все как обычно!!!
Re: VS bug: new int(1,2,"wtf")
От: Constructor  
Дата: 12.09.15 16:46
Оценка: 5 (1) +1
Здравствуйте, 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++ Александреску, как я понимаю.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.