do on exit
От: B0FEE664  
Дата: 28.03.13 14:29
Оценка:
Макросы не предлагать.

Что лучше variant 1 или 2?
И вообще, что бы вы сказали увидев это в проекте?

class A
{
  int m_n;
public:
  A(int n) : m_n(n) {}

  void f()
  { 
    if ( 0 == m_n )
      throw std::runtime_error("zero here");
    
    std::cout << m_n << std::endl;
  }
};


int main()
{
  boost::shared_ptr< std::list<A> > pList(new std::list<A>);

  pList->push_back(A(1));
  pList->push_back(A(2));
  pList->push_back(A(3));
  pList->push_back(A(4));
  pList->push_back(A(0));
  pList->push_back(A(5));

  void* pNull = NULL;

  while(pList->size())
  {
    try
    {
      A& rA = pList->front();
      //boost::shared_ptr< std::list<A> > OnExit(pList.get(), boost::mem_fn(&std::list<A>::pop_front)); // variant 1
      boost::shared_ptr<void> OnExit(pNull, boost::bind(&std::list<A>::pop_front, pList));              // variant 2
      
      rA.f();
    }
    catch(std::exception& e)
    {
      std::cout << "Error: " << e.what() << std::endl;
    }
  }

  std::cout << "Press any key to exit..." << std::endl;
  char ch = getch();
  
  return 0;
}

);

pList-
И каждый день — без права на ошибку...
exit shared_ptr bind
Re: do on exit
От: uzhas Ниоткуда  
Дата: 28.03.13 14:33
Оценка: :))) :))
Здравствуйте, B0FEE664, Вы писали:

BFE>И вообще, что бы вы сказали увидев это в проекте?


это недопустимо
класс A надо переименовать в CA
Re[2]: do on exit
От: B0FEE664  
Дата: 28.03.13 14:42
Оценка:
Здравствуйте, uzhas, Вы писали:

BFE>>И вообще, что бы вы сказали увидев это в проекте?

U>это недопустимо
U>класс A надо переименовать в CA

Вот вы смеётесь, а я сижу и думаю: commit'ить или не поймут...
И каждый день — без права на ошибку...
Re: do on exit
От: Abyx Россия  
Дата: 28.03.13 16:42
Оценка: +1
Здравствуйте, B0FEE664, Вы писали:

BFE>Макросы не предлагать.


BFE>Что лучше variant 1 или 2?

BFE>И вообще, что бы вы сказали увидев это в проекте?

я бы сказал что С++11 больше двух лет, а вы какой-то фигней занимаетесь.
In Zen We Trust
Re: do on exit
От: Erop Россия  
Дата: 28.03.13 19:00
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Что лучше variant 1 или 2?

BFE>И вообще, что бы вы сказали увидев это в проекте?

Зачем так сложно-то?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[2]: do on exit
От: B0FEE664  
Дата: 28.03.13 20:29
Оценка:
Здравствуйте, Erop, Вы писали:

BFE>>Что лучше variant 1 или 2?

BFE>>И вообще, что бы вы сказали увидев это в проекте?
E>Зачем так сложно-то?

А как надо? (В рамках старого стандарта).
И каждый день — без права на ошибку...
Re: do on exit
От: Caracrist https://1pwd.org/
Дата: 28.03.13 20:42
Оценка:
Здравствуйте, B0FEE664, Вы писали:


BFE>  while(!pList->empty())
BFE>  {
BFE>    try
BFE>    {
BFE>      pList->front().f();
BFE>    }
BFE>    catch(std::exception& e)
BFE>    {
BFE>      std::cout << "Error: " << e.what() << std::endl;
BFE>    }
        pList->pop_front();
BFE>  }

если у тебя pop_front упадёт, то catch тебе скорее всего уже не поможет, а, иначе, зачем все эти сложности?
~~~~~
~lol~~
~~~ Single Password Solution
Re[2]: do on exit
От: B0FEE664  
Дата: 28.03.13 23:18
Оценка:
Здравствуйте, Caracrist, Вы писали:

C>если у тебя pop_front упадёт, то catch тебе скорее всего уже не поможет,

C>а, иначе, зачем все эти сложности?

Это пример. В реальном коде всё много сложнее. Меня, собственно, интересует не то, как цикл изменить, а то , что вместо этой слишком сложной конструкции подставить:

boost::shared_ptr<void> OnExit(pNull, boost::bind(&std::list<A>::pop_front, pList));


Неужели в boost нет ничего более подходящего?
И каждый день — без права на ошибку...
Re[3]: do on exit
От: Evgeny.Panasyuk Россия  
Дата: 28.03.13 23:25
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Неужели в boost нет ничего более подходящего?


Boost.ScopeExit
Re: do on exit
От: Abyx Россия  
Дата: 28.03.13 23:34
Оценка: +1
Здравствуйте, B0FEE664, Вы писали:

BFE>
BFE>      A& rA = pList->front();
BFE>      //boost::shared_ptr< std::list<A> > OnExit(pList.get(), boost::mem_fn(&std::list<A>::pop_front)); // variant 1
BFE>      boost::shared_ptr<void> OnExit(pNull, boost::bind(&std::list<A>::pop_front, pList));              // variant 2
      
BFE>      rA.f();
BFE>


я бы использовал swap (или std::move)
{
    A a;
    swap(a, pList->front());
    // или
    // auto a = std::move(pList->front());

    pList->pop_front();

    a.f();
}
In Zen We Trust
Re[3]: do on exit
От: Erop Россия  
Дата: 29.03.13 04:58
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>А как надо? (В рамках старого стандарта).


Да хоть бы и в рамках старого.
Зачем-то в одном месте собраны и RAII и обработчик прерывания, и всё это ещё в цикл зачем-то засунуто...

Никак нельзя как-то концептуально проще быть?
Попробуй объяснить, что конкретно тебе надо-то?

Пройтись по списку, и выкинуть из него элементы, на которых падает какой-то метод?
Вызвать у всех элементов списка метод, даже если какой-то элемент кинет исключение?
Что-то ещё?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re: do on exit
От: Кодт Россия  
Дата: 29.03.13 07:12
Оценка: +3
Здравствуйте, B0FEE664, Вы писали:

BFE>Макросы не предлагать.


BFE>Что лучше variant 1 или 2?

Оба хуже

BFE>И вообще, что бы вы сказали увидев это в проекте?

"Я вам в отцы гожусь", сказал бы настоящий петербуржец.

Проще надо быть, и люди потянутся.
Логика работы ведь какая:
— дёрнуть f() у объекта, находящегося в голове списка
— диагностировать исключение
— удалить объект из головы

Если объекту неважно, лежит он в списке на момент вызова, — то сперва извлечь, потом дёрнуть.
Если важно, то так прямо и написать
while(!theList.empty())
{
  A& obj = theList.front();
  try { obj.f(); }
  catch(std::exception const& e) { report_error(e); }
  catch(...) { assertion_fault("неизвестное исключение! мы все умрём!"); throw; } // нет смысла дальше молотить наш цикл
  theList.pop_front(); // если исключение вылетит отсюда (?!), то тоже нет смысла дальше молотить цикл
}

Безо всяких scope guard-ов.
Перекуём баги на фичи!
Re[4]: do on exit
От: B0FEE664  
Дата: 29.03.13 11:00
Оценка: :))) :))) :)
Здравствуйте, Evgeny.Panasyuk, Вы писали:

BFE>>Неужели в boost нет ничего более подходящего?

EP>Boost.ScopeExit

Нет, макросы мне не нужны.
И каждый день — без права на ошибку...
Re[5]: do on exit
От: Evgeny.Panasyuk Россия  
Дата: 29.03.13 15:01
Оценка: +3
Здравствуйте, B0FEE664, Вы писали:

BFE>>>Неужели в boost нет ничего более подходящего?

EP>>Boost.ScopeExit
BFE>Нет, макросы мне не нужны.

Неужели если бы выбор стоял между тем что было в первом сообщении, и BOOST_SCOPE_EXIT, ты бы выбрал boost::shared_ptr, в котором лишние атомарные инструкции, лишний type erasure и менее читабельный код?
Re[6]: do on exit
От: B0FEE664  
Дата: 29.03.13 16:27
Оценка: :)
Здравствуйте, Evgeny.Panasyuk, Вы писали:

BFE>>>>Неужели в boost нет ничего более подходящего?

EP>>>Boost.ScopeExit
BFE>>Нет, макросы мне не нужны.

EP>Неужели если бы выбор стоял между тем что было в первом сообщении, и BOOST_SCOPE_EXIT, ты бы выбрал boost::shared_ptr, в котором лишние атомарные инструкции, лишний type erasure и менее читабельный код?

Вы ещё про заказ памяти посредством new внутри shared_count забыли

А как вы думаете, зачем я написал первую строчку в первом сообщении?
К счастью, выбор так не стоит, а если бы и стоял, то — да, предпочитаю стандартную практику без макросов см. документацию.


PS: Но кончилось всё как обычно: написал ещё один класс который только и делает, что pop_front в деструкторе вызывает.
И каждый день — без права на ошибку...
Re[7]: do on exit
От: Evgeny.Panasyuk Россия  
Дата: 29.03.13 16:49
Оценка:
Здравствуйте, B0FEE664, Вы писали:

EP>>Неужели если бы выбор стоял между тем что было в первом сообщении, и BOOST_SCOPE_EXIT, ты бы выбрал boost::shared_ptr, в котором лишние атомарные инструкции, лишний type erasure и менее читабельный код?

BFE>Вы ещё про заказ памяти посредством new внутри shared_count забыли

new и так уже нужен при type erasure.

BFE>А как вы думаете, зачем я написал первую строчку в первом сообщении?


Сообщение с вопросом про boost, я прочитал намного позже первого, поэтому был не в контексте.

BFE>PS: Но кончилось всё как обычно: написал ещё один класс который только и делает, что pop_front в деструкторе вызывает.


Это кстати намного лучше shared_ptr, а при вероятности реиспользования (если получится дать хорошее имя) даже лучше чем scope exit.
Re[8]: do on exit
От: B0FEE664  
Дата: 29.03.13 17:16
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>>>Неужели если бы выбор стоял между тем что было в первом сообщении, и BOOST_SCOPE_EXIT, ты бы выбрал boost::shared_ptr, в котором лишние атомарные инструкции, лишний type erasure и менее читабельный код?

BFE>>Вы ещё про заказ памяти посредством new внутри shared_count забыли
EP>new и так уже нужен при type erasure.
type erasure можно и на ссылках смастерить. Впрочем зачем type erasure у shared_ptr мне не понятно.

BFE>>PS: Но кончилось всё как обычно: написал ещё один класс который только и делает, что pop_front в деструкторе вызывает.

EP>Это кстати намного лучше shared_ptr, а при вероятности реиспользования (если получится дать хорошее имя) даже лучше чем scope exit.
Как показывает практика, вероятность реиспользования таких классов стремится к нулю.
И каждый день — без права на ошибку...
Re[9]: do on exit
От: Evgeny.Panasyuk Россия  
Дата: 29.03.13 19:21
Оценка:
Здравствуйте, B0FEE664, Вы писали:

EP>>>>Неужели если бы выбор стоял между тем что было в первом сообщении, и BOOST_SCOPE_EXIT, ты бы выбрал boost::shared_ptr, в котором лишние атомарные инструкции, лишний type erasure и менее читабельный код?

BFE>>>Вы ещё про заказ памяти посредством new внутри shared_count забыли
EP>>new и так уже нужен при type erasure.
BFE>type erasure можно и на ссылках смастерить. Впрочем зачем type erasure у shared_ptr мне не понятно.

Ну а как без type erasure сохранить произвольный deleter, не меняя тип shared_ptr<void>?
boost::shared_ptr<void> OnExit(pNull, boost::bind(&std::list<A>::pop_front, pList));

Допустим в качестве deleter'а будет функтор у которого sizeof=1024.
#include <boost/shared_ptr.hpp>
#include <iostream>
#include <ostream>

using namespace std;

struct Deleter
{
    char stuff[1024];
    void operator()(void*){}
};

int main()
{
    boost::shared_ptr<void> p(0,Deleter());
    cout << "sizeof(p)=" << sizeof(p) << endl;
    cout << "sizeof(Deleter)=" << sizeof(Deleter) << endl;
}

stdout:
sizeof(p)=16
sizeof(Deleter)=1024


BFE>Как показывает практика, вероятность реиспользования таких классов стремится к нулю.


Да, согласен.
Re[7]: do on exit
От: Erop Россия  
Дата: 29.03.13 19:33
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>PS: Но кончилось всё как обычно: написал ещё один класс который только и делает, что pop_front в деструкторе вызывает.


А зачем?
Можешь понятно пояснить, что тебе надо-то было?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[10]: do on exit
От: B0FEE664  
Дата: 02.04.13 09:18
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

BFE>>type erasure можно и на ссылках смастерить. Впрочем зачем type erasure у shared_ptr мне не понятно.

EP>Ну а как без type erasure сохранить произвольный deleter, не меняя тип shared_ptr<void>?

Не подумал
И каждый день — без права на ошибку...
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.