дизайн с обобщенной функцией
От: Аноним  
Дата: 09.10.07 10:41
Оценка:
хочу посоветоваться как лучше сделать
вот у меня есть такой код
while (endRay())
{
  // перебираем точки на луче;
}

endRay() это либо сравнить с точкой, либо считать количество пройденных элементов, либо сравнивать значение на луче.
сперва думал что functor то что нужно. но как данные обновлять в лупе ?
спасибо!
Re: дизайн с обобщенной функцией
От: jazzer Россия Skype: enerjazzer
Дата: 09.10.07 10:42
Оценка:
Здравствуйте, Аноним, Вы писали:

А>хочу посоветоваться как лучше сделать

А>вот у меня есть такой код
А>
А>while (endRay())
А>{
А>  // перебираем точки на луче;
А>}
А>

А>endRay() это либо сравнить с точкой, либо считать количество пройденных элементов, либо сравнивать значение на луче.
А>сперва думал что functor то что нужно. но как данные обновлять в лупе ?

недостаточно входных данных
опиши задачу подробнее
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[2]: дизайн с обобщенной функцией
От: Аноним  
Дата: 09.10.07 11:52
Оценка:
J>недостаточно входных данных
J>опиши задачу подробнее
так наверное будет понятнее: вот тестовый код, который нагромоздил.
class BaseFunctor
{
public:
    virtual bool operator()(const int & idata) { return false;}
};

template <class T>
class DerivedFunctor: public BaseFunctor
{
private:
    bool (T::*fpt_)(const int & idata); 
    T * ptTObject_;
public:
    DerivedFunctor(T* ptTObject, bool (T::*fpt)(const int & idata))
    { ptTObject_ = ptTObject; fpt_=fpt;}
    virtual bool operator()(const int & idata) { return (*ptTObject_.*fpt_)(idata);}
};

// классы задающие условия
// по индексу
class IndexEndPath
{
private:
    int endI_; 
public:
    IndexEndPath(const int & endI) {endI_=endI;}

    bool check(const int & idata) {return idata != endI_;}
};
// по количеству элементов
class NrElemsEndPath
{
private:
    int nrElems_;
public:
    NrElemsEndPath(const int & nrElems) {nrElems_ = nrElems;}

    bool check(const int & idata) {return idata != nrElems_;}
};

int main(int argc, char * argv[])
{
    int i=0;
    std::cout << "end by index\n";
    IndexEndPath objIndexEndPath(10);
    DerivedFunctor<IndexEndPath> conditionIndex(&objIndexEndPath, &IndexEndPath::check);
    while (conditionIndex(i))
    {
        std::cout << i++ << std::endl;
    }

    std::cout << "end by nr of elements\n";
    i=0;
    NrElemsEndPath objNrElemsEndPath(5);
    DerivedFunctor<NrElemsEndPath> conditionNrElems(&objNrElemsEndPath, &NrElemsEndPath::check);
    while (conditionNrElems(i))
    {
        std::cout << i++ << std::endl;
    }

    std::cin.get();
    return 0;
}

все работает, но что делать если вместо i хочется подставить значение double или что-то еще ? можно ли проще ?
Re[3]: дизайн с обобщенной функцией
От: jazzer Россия Skype: enerjazzer
Дата: 09.10.07 15:53
Оценка:
Здравствуйте, Аноним, Вы писали:

J>>недостаточно входных данных

J>>опиши задачу подробнее
А>так наверное будет понятнее: вот тестовый код, который нагромоздил.

А>все работает, но что делать если вместо i хочется подставить значение double или что-то еще ? можно ли проще ?


А зачем тебе наследование в классе функтора, если не секрет?

P,S, пользуйся, плиз, раскраской С++ (ccode) — неудобно читать голый серый текст
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[4]: дизайн с обобщенной функцией
От: Аноним  
Дата: 09.10.07 22:32
Оценка:
J>А зачем тебе наследование в классе функтора, если не секрет?

действительно, здесь не нужно.
а что можно прикрутить, чтобы в качестве аргумента и double или что-нибудь еще можно было передавать.
спасибо!
Re: дизайн с обобщенной функцией
От: andrey.desman  
Дата: 10.10.07 01:24
Оценка:
Здравствуйте, Аноним, Вы писали:

А>endRay() это либо сравнить с точкой, либо считать количество пройденных элементов, либо сравнивать значение на луче.

А>сперва думал что functor то что нужно. но как данные обновлять в лупе ?
А>спасибо!

Наверное нечто подобное Java iterators — это то, что тебе нужно.

Что-то вроде:


class IndexIterator
{
   private:
      Point *points_;
      int i_;
      int end_;
      int step_;

   public:
      IndexIterator(Point *p, int start, int end, int step): points_(p), i_(start), end_(end), step_(step) {}

      bool  hasNext       { return i_ < end_; }
      Point *getNext()    { return points_[i_]; }
      void  moveForward() { i_ += step_; }
};

void foo()
{
   Points *p;

   IndexIterator i(p, 0, 10, 1);

   while (i.hasNext())
   {
      Point *p = i.getNext();
      // Do ....
      i.moveForward();
   }
}
Re[5]: дизайн с обобщенной функцией
От: jazzer Россия Skype: enerjazzer
Дата: 10.10.07 01:37
Оценка:
Здравствуйте, Аноним, Вы писали:


J>>А зачем тебе наследование в классе функтора, если не секрет?


А>действительно, здесь не нужно.

А>а что можно прикрутить, чтобы в качестве аргумента и double или что-нибудь еще можно было передавать.
А>спасибо!

Ну, например, так:
template <class T, class Arg>
class DerivedFunctor
{
private:
    T * p_;
    bool (T::*fpt_)(const Arg &); 
public:
    DerivedFunctor(T* p, bool (T::*fpt)(const Arg &)) : p_(p), fpt_(fpt) {}
    bool operator()(const Arg & idata) const { return (*p_.*fpt_)(idata); }
};


и потом
    const DerivedFunctor<IndexEndPath, int> conditionIndex(&objIndexEndPath, &IndexEndPath::check);
    const DerivedFunctor<NrElemsEndPath, double> conditionNrElems(&objNrElemsEndPath, &NrElemsEndPath::check);

оно?

Этот вариант самый оптимальный по скорости, но если скорость не критична и издержки на виртуальный вызов приемлемы, то синтаксис можно еще больше упростить.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re: дизайн с обобщенной функцией
От: Кодт Россия  
Дата: 10.10.07 17:01
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>хочу посоветоваться как лучше сделать

А>вот у меня есть такой код
А>
А>while (endRay())
А>{
А>  // перебираем точки на луче;
А>}
А>

А>endRay() это либо сравнить с точкой, либо считать количество пройденных элементов, либо сравнивать значение на луче.

Может быть, всё-таки это итератор
for(Some i=SomeBegin(); i!=SomeEnd(); ++i)
{
    // *i - это текущая точка луча
}

что позволит использовать всевозможные алгоритмы — for_each, transform, find_if...

Тут есть два подхода:
1) Использовать "родные" итераторы коллекции точек и предварительно находить итератор конца подпоследовательности
Collection::iterator stop = // на выбор:
    coll.end() // все
    std::find(coll.begin(), coll.end(), value) // отсечка по значению
    std::find_if(coll.begin(), coll.end(), predicate) // отсечка по условию
    coll.begin() + n // заданное количество

for_each(coll.begin(), stop, visitor_func);

2) Использовать синтетические итераторы, которые разными способами знают, что такое "конец" (смотри boost/iterator)
Этот подход оправдан в том случае, если родные итераторы — всего лишь Input Iterator, и невозможно (либо дорого) неразрушающим способом получить итератор конца.
... << RSDN@Home 1.2.0 alpha rev. 655>>
Перекуём баги на фичи!
Re[2]: дизайн с обобщенной функцией
От: Аноним  
Дата: 11.10.07 11:36
Оценка:
да, похоже, что это лучшее решение. не оч силен писать итераторы — попробую разобраться.
спасибо!
Re[3]: дизайн с обобщенной функцией
От: Кодт Россия  
Дата: 11.10.07 13:30
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>да, похоже, что это лучшее решение. не оч силен писать итераторы — попробую разобраться.

А>спасибо!

Думаю, что по-первости можешь ограничиться родными итераторами твоей коллекции.
Если только твоя коллекция не есть нечто экзотическое.
... << RSDN@Home 1.2.0 alpha rev. 655>>
Перекуём баги на фичи!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.