прервать цепочки вызовов, как??
От: Аноним  
Дата: 11.07.08 14:59
Оценка:
с какой стороны подойти, не пойму...
есть иерархия классов, все имеющие свою версию MyClass::run(); есть вектор std::vector<MyClass*> pClasses;
в какой-то момент времени нужно все их пробежать, т.е. отрабатывает for_each(pClasses.begin(), pClasses.end(), Execute()); где
class Execute {
public:
    void operator()(const MyClass *p) const {
        p->run();
    }
};

но фишка в том, что на определенном шаге энному члену нужно иметь возможность каким-то образом прекратить все дальнейшие "запуски" MyClass::run() у оставшейся цепочки, т.е. какбы сэмулировать завершение вышеуказанного for_each(...);
есть идеи? был бы признателен.
Re: прервать цепочки вызовов, как??
От: Vamp Россия  
Дата: 11.07.08 15:21
Оценка:
А>есть идеи? был бы признателен.
Исключение?
Да здравствует мыло душистое и веревка пушистая.
Re[2]: прервать цепочки вызовов, как??
От: Аноним  
Дата: 11.07.08 15:34
Оценка:
Здравствуйте, Vamp, Вы писали:

А>>есть идеи? был бы признателен.

V>Исключение?
вариант!
я только что тоже придумал вариант -- с хранением ссылки "MyClass &parent" на "родительский"/"вышестоящий" MyClass, которую мы будем помещать в каждый MyClass. а в функтор выше добавляем условие "_Parent->stillRunning() == true". но такой подход мне не нравится — если будет большая вложенность объектов др в друга, будут десятки холостых таких проверок.
вариант с исключениями, думаю, подходит лучше!
Re: прервать цепочки вызовов, как??
От: Pretender  
Дата: 11.07.08 15:53
Оценка: 1 (1) +1
Здравствуйте, Аноним, Вы писали:

А>с какой стороны подойти, не пойму...

А>есть иерархия классов, все имеющие свою версию MyClass::run(); есть вектор std::vector<MyClass*> pClasses;
А>в какой-то момент времени нужно все их пробежать, т.е. отрабатывает for_each(pClasses.begin(), pClasses.end(), Execute()); где
А>
А>class Execute {
А>public:
А>    void operator()(const MyClass *p) const {
        p->>run();
А>    }
А>};
А>

А>но фишка в том, что на определенном шаге энному члену нужно иметь возможность каким-то образом прекратить все дальнейшие "запуски" MyClass::run() у оставшейся цепочки, т.е. какбы сэмулировать завершение вышеуказанного for_each(...);
А>есть идеи? был бы признателен.

Run/Execute возвращает true если надо прервать цепочку, иначе false.

Потом вместо for_each вызываем find_if.

Или я чего-то не понимаю?
Re[2]: прервать цепочки вызовов, как??
От: Аноним  
Дата: 11.07.08 16:18
Оценка:
Здравствуйте, Pretender, Вы писали:

хмм, распиши плз поподробнее. особливо недопонял я про find_if.
Re: прервать цепочки вызовов, как??
От: merk Россия  
Дата: 11.07.08 16:23
Оценка: +3
Здравствуйте, Аноним, Вы писали:

А>с какой стороны подойти, не пойму...

А>есть иерархия классов, все имеющие свою версию MyClass::run(); есть вектор std::vector<MyClass*> pClasses;
А>в какой-то момент времени нужно все их пробежать, т.е. отрабатывает for_each(pClasses.begin(), pClasses.end(), Execute()); где
А>
А>class Execute {
А>public:
А>    void operator()(const MyClass *p) const {
        p->>run();
А>    }
А>};
А>

А>но фишка в том, что на определенном шаге энному члену нужно иметь возможность каким-то образом прекратить все дальнейшие "запуски" MyClass::run() у оставшейся цепочки, т.е. какбы сэмулировать завершение вышеуказанного for_each(...);
А>есть идеи? был бы признателен.

скажите...а почему вы пишете for_each, обьявляя читателю, что вы заказываете некую обработку КАЖДОГО элемента вектора, а потом заявляете, что каждый элемент вектора вам обрабатывать и не нужно?
может в консерватории чего не так???
или вы считаете что дословный перевод for_each тут неуместен?
Re[3]: прервать цепочки вызовов, как??
От: ilnar Россия  
Дата: 11.07.08 16:38
Оценка: 1 (1) +1
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, Pretender, Вы писали:


А>хмм, распиши плз поподробнее. особливо недопонял я про find_if.



class Execute {
public:
    bool operator()(const MyClass *p) const {
        p->run();
        if(нужно прервать) 
            return true;
        return false;
    }
};
...
find_if(pClasses.begin(), pClasses.end(), Execute());
Re[2]: прервать цепочки вызовов, как??
От: Аноним  
Дата: 11.07.08 16:47
Оценка:
Здравствуйте, merk, Вы писали:

M>скажите...а почему вы пишете for_each, обьявляя читателю, что вы заказываете некую обработку КАЖДОГО элемента вектора, а потом заявляете, что каждый элемент вектора вам обрабатывать и не нужно?

M>может в консерватории чего не так???
M>или вы считаете что дословный перевод for_each тут неуместен?

в первом посте я вроде бы внятно описал суть проблемы -- пробегаться по элементам вектора и вызывать ф-цию-член run() последовательно для каждого элемента до тех пор, пока определенное условие не станет истинным. согласен, for_each ненаглядно для описания, но как бы я мог иначе описать суть вопроса?
вся фишка в том, что нек. MyClass* могут являться указателями на MyClassList, т.е. что-то типа:
class MyClass{
public:
  //...
  virtual void run(){
     //какие-то действия
  }
};

class Execute{
public:
  operator()(const MyClass *p){
    p->run();
 }
};

class MyClassList : public MyClass{
  std::vector<MyClass *> _list;
public:
  //...
  void run(){
    std::for_each(_list.begin(); _list.end(); Execute()); отрабатывает целый список
  }
};


std::vector<MyClass *> entries;
//заполнили
//здесь необходимо пробежаться по entries и для кажд его элемента запустить его ф-цию-член run(), НО по достижении определенного условия, которое может произойти при вызове текущей run() для текущегшо указателя прекратить полностью ВСЕ дальнейшие переборы (в том числе и вложенные).
пардон, если я сразу не понятно все описал.
Re[4]: прервать цепочки вызовов, как??
От: Аноним  
Дата: 11.07.08 16:55
Оценка:
Здравствуйте, ilnar, Вы писали:

I>Здравствуйте, Аноним, Вы писали:


А>>Здравствуйте, Pretender, Вы писали:


А>>хмм, распиши плз поподробнее. особливо недопонял я про find_if.



I>
I>class Execute {
I>public:
I>    bool operator()(const MyClass *p) const {
        p->>run();
I>        if(нужно прервать) 
I>            return true;
I>        return false;
I>    }
I>};
I>...
I>find_if(pClasses.begin(), pClasses.end(), Execute());
I>
Re[5]: прервать цепочки вызовов, как??
От: Аноним  
Дата: 11.07.08 17:04
Оценка:
А>Здравствуйте, ilnar
спасибо. это то самое.
Re[2]: прервать цепочки вызовов, как??
От: Centaur Россия  
Дата: 12.07.08 04:53
Оценка: 2 (2)
Здравствуйте, Pretender, Вы писали:

P>Run/Execute возвращает true если надо прервать цепочку, иначе false.


P>Потом вместо for_each вызываем find_if.


P>Или я чего-то не понимаю?


Имя find_if несёт семантику поиска. Как правило, поиск не даёт побочных эффектов. В то время как метод run без параметров явно вызывается ради побочных эффектов.

Думаю, семантически правильно было бы написать отдельный алгоритм с отдельным именем (скажем, for_each_while или for_each_until), пусть даже и реализованный как обёртка над find_if.
Re: прервать цепочки вызовов, как??
От: IROV..  
Дата: 12.07.08 12:59
Оценка: 1 (1) +4
Здравствуйте, Аноним, Вы писали:

А>с какой стороны подойти, не пойму...

А>есть иерархия классов, все имеющие свою версию MyClass::run(); есть вектор std::vector<MyClass*> pClasses;
А>в какой-то момент времени нужно все их пробежать, т.е. отрабатывает for_each(pClasses.begin(), pClasses.end(), Execute()); где

Ох уж эти космонавты, им звезды звезды, а у нас в селе все просто делается.

for( std::vector<MyClass *>::iterator
  it = pClasses.begin(),
  it_end = pClasses.end();
it != it_end;
++it )
{
  if( it->run() == false )
  {
    break;
  }
}


я не волшебник, я только учусь!
Re[2]: прервать цепочки вызовов, как??
От: techgl  
Дата: 12.07.08 15:39
Оценка:
Здравствуйте, Pretender, Вы писали:

P>Run/Execute возвращает true если надо прервать цепочку, иначе false.

В это случае не понятна будет причина прерывания. Исключение более информативно.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[3]: прервать цепочки вызовов, как??
От: Pretender  
Дата: 12.07.08 17:58
Оценка:
Здравствуйте, techgl, Вы писали:

T>Здравствуйте, Pretender, Вы писали:


P>>Run/Execute возвращает true если надо прервать цепочку, иначе false.

T>В это случае не понятна будет причина прерывания. Исключение более информативно.

1. Зато более затратно.
2. Программа должна поддерживать безопастность исключений.
3. Да и не для того они были придуманы.
4. В задаче не сказано что нам важно знать причину почему надо прервать выполнение. Плюс дошли или нет до конца можем узнать по результату find_if.
Re[3]: прервать цепочки вызовов, как??
От: Pretender  
Дата: 12.07.08 18:03
Оценка:
Здравствуйте, Centaur, Вы писали:

C>Имя find_if несёт семантику поиска. Как правило, поиск не даёт побочных эффектов. В то время как метод run без параметров явно вызывается ради побочных эффектов.

усть даже и реализованный как обёртка над find_if.

Согласен. Но семантика for_each ещё сильней нарушена.

offtop: Нехватает алгоритмов and(iterator, iterator, bool(value))/or(...) работающих до первого false/true
Re[4]: прервать цепочки вызовов, как??
От: techgl  
Дата: 13.07.08 10:39
Оценка:
Здравствуйте, Pretender, Вы писали:

P>1. Зато более затратно.

Это самое узкое место программы? В исходной задаче, опять же, ничего не написано о требованиях, чтобы оценивать что затратно.

P>3. Да и не для того они были придуманы.

В методе run что-то пошло не так, это исключительная ситуация, которая к тому же, прекращает всю дальнейшую цепочку. Вполне опревдано тут исключение.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[2]: прервать цепочки вызовов, как??
От: Аноним  
Дата: 13.07.08 10:52
Оценка:
сейчас все пересмотрел, и решил остановиться на простом цикле, предложенным выше уважаемым IROV...
думаю, это верное решение, т.к. не надо усложнять сверх необходимого, и все должно быть прозрачно для понимания. а исключение -- в любом случае явл. накладными расходами.
всем спасибо еще раз за пояснения.
Re[5]: прервать цепочки вызовов, как??
От: skeptik_  
Дата: 13.07.08 11:38
Оценка:
Здравствуйте, techgl, Вы писали:

P>>3. Да и не для того они были придуманы.

T>В методе run что-то пошло не так, это исключительная ситуация, которая к тому же, прекращает всю дальнейшую цепочку. Вполне опревдано тут исключение.
Этого автор не сказал. Если прерывание является штатной ситуацией, то надо юзать простой цикл. find_if же обфускирует семантику происходящего.
Re[2]: прервать цепочки вызовов, как??
От: landerhigh Пират  
Дата: 14.07.08 01:14
Оценка:
Здравствуйте, IROV.., Вы писали:

IRO>Здравствуйте, Аноним, Вы писали:


А>>с какой стороны подойти, не пойму...

А>>есть иерархия классов, все имеющие свою версию MyClass::run(); есть вектор std::vector<MyClass*> pClasses;
А>>в какой-то момент времени нужно все их пробежать, т.е. отрабатывает for_each(pClasses.begin(), pClasses.end(), Execute()); где

IRO>Ох уж эти космонавты, им звезды звезды, а у нас в селе все просто делается.


Не космонавты, а эстеты.

Нам что-нить вроде do_until или for_each_until подавай. Хотя это же можно за пять минут на коленке сляпать
www.blinnov.com
Re[3]: прервать цепочки вызовов, как??
От: IROV..  
Дата: 14.07.08 09:36
Оценка:
Здравствуйте, landerhigh, Вы писали:

L>Не космонавты, а эстеты.


L>Нам что-нить вроде do_until или for_each_until подавай. Хотя это же можно за пять минут на коленке сляпать


Иногда эти вещи прячутся от таких эстетов.

#    include <stdio.h>
#    include <vector>
#    include <algorithm>

class MyClass
{
public:
    explicit MyClass( bool _until )
        : m_until(_until)
    {

    }
public:
    bool update() const
    {
        printf("1\n");
        return m_until;
    }

protected:
    bool m_until;
};

int main()
{
    std::vector<MyClass *> v;
    v.push_back( new MyClass( false ) );
    v.push_back( new MyClass( false ) );
    v.push_back( new MyClass( false ) );
    v.push_back( new MyClass( true ) );
    v.push_back( new MyClass( false ) );

    struct UpdateUntil
    {
        bool operator () ( MyClass * _my )
        {
            return _my->update();
        }
    };

    std::find_if( v.begin(), v.end(), UpdateUntil() );
}





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