Зарание простите за такой длинный и пространный пост...
СообщениеАвтор: remark
Дата: 19.07.07
remark'a
из потока "оптимизация возвращаемого значения" пересеклось с некоторыми моими мыслями.
Мысли старые, но все не хватало вермени как следует разобраться...Пытался поискать
аналоги, но поиск на RSDN не работает
Первая идея: оператор постфиксного инремента
class foo
{
private:
class deferred_increment
{
public:
typedef foo master_type;
explicit
deferred_increment(master_type& m): m_(m) {}
~deferred_increment() { ++m_; }
private:
master_type& m_;
};
public:
//prefix ++
foo& operator++()
{
/* ... do increment ... */
return *this;
}
//postfix ++
const foo operator++(int)
{
deferred_increment inc(*this);
return *this;
// увеличили *this в деструкторе
// ни одной временной переменной не надо
}
};
Если так можно (т.е. безопасно) делать, то почему так никто не делает? Я просмотрел
пару реализаций STL и весь Boost -- ничего такого...
Ещё брутальнее: безопасный по исключениям stack::pop(), возвращающий значение
template <typename _Tp, typename _Sequence>
class stack
{
/* ... pop(), top(), typedefs, ... */
private:
class deferred_pop
{
public:
typedef stack<value_type, container_type> master_type;
explicit deferred_pop(master_type& m): m_(m) {}
~deferred_pop()
{
if (!std::uncaught_exception())
m_.pop();
}
private:
master_type& m_;
};
public:
value_type vpop()
{
deferred_pop p(*this)
return top();
// вызов деструктора p
}
/*...*/
};
Если исключение выброшено -- деструктор ничего не делает, если нет -- делает.
Вроде бы сильная (strong) гарантия безопасности по исключениям, семантика транзакции
налицо... Тестировал в MSVS 8 и gcc 4.1.1 -- работает правильно.
Но что-то меня здесь все-таки беспокоит... Может быть, просто я начитался Саттера,
который в "те времена" не знал ни одного хорошего использования (good use) функции
uncaught_exception()?
Буду благодарен за любой комментарий...
iZverg