RFC: Польза от деструкторов локальных переменных
От: Не могу выдумать корректный ник АКА iZve  
Дата: 20.07.07 10:15
Оценка: 1 (1)
Зарание простите за такой длинный и пространный пост...

Сообщение
Автор: 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
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.