Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Использование std::for_each(...)  (Прочитано 24695 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Pu
Большой босс

ru
Offline Offline
78


« : 22-09-2004 06:33 » 

из MSDN:
Код:
class StoreVals   
{
   int val;
public:
   StoreVals ( ) { val = 0; }
   StoreVals ( int j ) { val = j; }

   int lessconst ( int k )  |val -= k; return val; }
};

int main( )
{
   vector <StoreVals *> v1;

   v1.push_back( &StoreVals ( 5 ) );
   v1.push_back( &StoreVals ( 10 ) );
   v1.push_back( &StoreVals ( 15 ) );
   v1.push_back( &StoreVals ( 20 ) );
   v1.push_back( &StoreVals ( 25 ) );

   // Use of mem_fun1 calling member function through a pointer
   // subtract 5 from each value in the vector using lessconst ( )
   for_each( v1.begin( ), v1.end( ),
      bind2nd ( mem_fun1<int, StoreVals,int> ( &StoreVals::lessconst ), 5 ) );   
}

Вопрос - могу ля и как либо вызвать в for_each() функцию-член класса с 2-мя и более аргументов?
Или только в цикле Жаль.
« Последнее редактирование: 01-12-2007 16:02 от Алексей1153++ » Записан

Насколько я опытен? Достаточно, чтобы понимать, что дураков нельзя заставить думать по–другому, но недостаточно, чтобы отказаться от попыток это сделать.
(с) Артур Джонс
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 22-09-2004 07:03 » 

так ты это и делаешь  Я шокирован! их у тебя целых 5!
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
stragner
Гость
« Ответ #2 : 22-09-2004 07:52 » 

dimka, лично я вижу только два, может у меня глюк Отлично
Записан
Pu
Большой босс

ru
Offline Offline
78


« Ответ #3 : 22-09-2004 09:53 » 

dimka,  5 это один аргумент типа int.
я вижу только один. Улыбаюсь. он там один и есть. Ага
Но проблем я вроде понял как решить. (Сереге отдельный сенкс Улыбаюсь). Нужно пользоваться биндингом на несколько переменных. В STL такого нет , но вот Серега посоветовал либу Loki у них реализован биндинг до 15 аргументов, в BOOST нашел до 10 аргументов. Привинчу либу какую нить , покажу как сделал.
Записан

Насколько я опытен? Достаточно, чтобы понимать, что дураков нельзя заставить думать по–другому, но недостаточно, чтобы отказаться от попыток это сделать.
(с) Артур Джонс
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #4 : 22-09-2004 10:39 » 

просто у меня вопрос родил ассоциацию с параметрами функции нити процесса (thread) в винде. Там тоже 1 аргумент типа void** Улыбаюсь. Мож вы чего-нибудь иное тут обсуждаете Улыбаюсь
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Pu
Большой босс

ru
Offline Offline
78


« Ответ #5 : 22-09-2004 11:01 » 

dimka, да , типа,  другое.  Улыбаюсь. Приблизительно вот что - для каждого указателя на обект типа StoreVals хранимого в векторе  вызывается его метод
int lessconst(int ),
это можно сделать обычным способом перебрав весь диапазон - типа так:
Код:
for( vector<StoreVals *>::iterator it = v1.begin( ); it != v1.end( ); it++)
      (*it)->lessconst(5); 
а можно сделать используя алгоритм for_each();
Код:
for_each( v1.begin( ), v1.end( ), 
      bind2nd ( mem_fun1<int, StoreVals,int>
           ( &StoreVals::lessconst ), 5 ) ); 
вот меня и заинтересовал вопрос как тоже самое сделать , если  lessconst() будет иметь два аргумента.   Вот такой я вот
« Последнее редактирование: 01-12-2007 16:05 от Алексей1153++ » Записан

Насколько я опытен? Достаточно, чтобы понимать, что дураков нельзя заставить думать по–другому, но недостаточно, чтобы отказаться от попыток это сделать.
(с) Артур Джонс
lapulya
Молодой специалист

ru
Offline Offline

« Ответ #6 : 22-09-2004 12:08 » 

напиши функтор который при создании (в конструкоре получает сколько угодно параметров), а при вызове соотвественно подставляет их в функцию  очередного объекта StoreVals

типа такого

class Myfuntor
{
int i;
int j;
int k;
public:
MyFunctor(int _i, int _j, int _k) : i(_i), j(_j), k(_K) {}

void operator () (//немопню чего тут писать)
{
    (*iter)->functionMember(i, j, k);
}
};

и вызывай его в for_each ну или типа того... так помоему можно (короче берем книгу Effective STL и там ответ!!!)
Записан

С уважением Lapulya
Pu
Большой босс

ru
Offline Offline
78


« Ответ #7 : 22-09-2004 12:21 » 

lapulya, страницу? книга предо мной Ага. иль хотя б номер совета.
не все так просто.
проблем еще и в том что используется mem_fun()  Улыбаюсь
Записан

Насколько я опытен? Достаточно, чтобы понимать, что дураков нельзя заставить думать по–другому, но недостаточно, чтобы отказаться от попыток это сделать.
(с) Артур Джонс
lapulya
Молодой специалист

ru
Offline Offline

« Ответ #8 : 22-09-2004 20:56 » 

чегото заяц я тебя не пойму... коли нужен универсаньный метод который позволял бы выполнять любую! функцию-член объекта с произвольным! количеством параметров, то такого нет (можно конечно наплодить шаблонов не меряно типа под 2 параметра под 3 и т.д., но это не красиво и не совсем универсально потому как может у меня есть функция член с 10000 параметров)
если речь идет о нескольник функциях (наперед заданных... естессно мы знаем количество из параметров) то я уже казал как это делать, повторю
Код:
class MyClass
{
public:
void f(int, int, char);
};

class functor
{
int a;
inr b;
char c;

public:
functor(int _a, int _b, char _c) : a(_a), b(_b), c(_c) {}
void operator () (MyClass * object)
{
object->f(a,b,c);
}
}

void main()
{
std::vector<MyClass *> v;

v.push_back(new MyClass);
v.push_back(new MyClass);
v.push_back(new MyClass);
v.push_back(new MyClass);
v.push_back(new MyClass);

std::for_each(v.begin(), v.end(), functor(3,5,'n'));
}
вот работает как часы... но может тебе не этого надо...
объясни бодробнее
« Последнее редактирование: 01-12-2007 16:07 от Алексей1153++ » Записан

С уважением Lapulya
lapulya
Молодой специалист

ru
Offline Offline

« Ответ #9 : 22-09-2004 20:59 » 

т.е. какой уровень универсальности интересует
независимость от типа объекта
независимость от вызываемой функции-мембера
независимость от количества параметрой
или какиенить комбинации этих свойств или ваще ВСЕ!!! Отлично
Записан

С уважением Lapulya
lapulya
Молодой специалист

ru
Offline Offline

« Ответ #10 : 22-09-2004 21:53 » 

если ты юзаешь только несколько таких функций ну например три, то ты знаешь сколько у них параметров там... ну 2, 35 и 55, можно написать три шаблона которые будут завязаны ТОЛЬКО на количество параметров и ни на чито другое -> пишем их и юзаем с произвольными объектами, с произвольными функциями этих объектов, с произвольными типами параметров этих функций-мемберов, НО!!! с жестко заданным колличеством параменров (соответственно 2, 35 или 55)

 Отлично это я все ни как не успакоюсь... до кровати все ни как дойти не могу Отлично
Записан

С уважением Lapulya
Pu
Большой босс

ru
Offline Offline
78


« Ответ #11 : 23-09-2004 05:52 » 

lapulya, спасибо за решение. Мне хотелось просто чтобы использовались функции-члены. Без всяких дополнительных наворотов и не более того. В книжке Effective STL как раз и описываются способ решения этого с помощью mem_fun(). Потому у мене непонятка и возникла. Да и функторами пространство имен глобал не охота было заваливть. Хотя есть идэя просто для своих использовать свой namespace. А еще попробовал и так -
Код:
class MyClass 
{
public:
int f(int a, int b, char c)
{
return 28;
}
class functor
{
int a;
int b;
char c;

public:
functor(int _a, int _b, char _c) : a(_a), b(_b), c(_c) {}
void operator () (MyClass * object)
{
object->f(a,b,c);
}
};
};

void main()
{
std::vector<MyClass *> v;

v.push_back(new MyClass);
v.push_back(new MyClass);
v.push_back(new MyClass);
v.push_back(new MyClass);
v.push_back(new MyClass);

std::for_each(v.begin(), v.end(), MyClass::functor(3,5,'n'));
}
тож работает  Улыбаюсь . Спасибки бальшие. Горизонты раздвинулись.  Ага .
« Последнее редактирование: 01-12-2007 16:18 от Алексей1153++ » Записан

Насколько я опытен? Достаточно, чтобы понимать, что дураков нельзя заставить думать по–другому, но недостаточно, чтобы отказаться от попыток это сделать.
(с) Артур Джонс
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #12 : 23-09-2004 05:53 » 

lapulya, ах вот вы о чём тут говорите Улыбаюсь дак это у Страуструпа написано открытым текстом, про функтор. Вот я и впал в недоумение, какие такие параметры, куда и зачем Улыбаюсь
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Pu
Большой босс

ru
Offline Offline
78


« Ответ #13 : 23-09-2004 06:09 » 

Класс!!! :!:  и еще один изврат на тему  Ага
Код:
class MyClass 
{
public:
int f(int a, int b, char c)
{
return 28;
}

};
 
namespace functors
{
template<class t, class arg1, class arg2, class arg3>
class functor
{
arg1 a;
arg2 b;
arg3 c;

public:
functor(arg1 _a, arg2 _b, arg3 _c) : a(_a), b(_b), c(_c) {}
void operator () (t * object)
{
object->f(a,b,c);
}
};
}

int _tmain(int argc, _TCHAR* argv[])
{
std::vector<MyClass *> v;

v.push_back(new MyClass);
v.push_back(new MyClass);
v.push_back(new MyClass);
v.push_back(new MyClass);
v.push_back(new MyClass);

std::for_each(v.begin(), v.end(), functors::functor<MyClass, int, int, char>(3,5,'n'));
return 0;
}
по-моему в Loki я такое и видел   Вот такой я вот .
« Последнее редактирование: 01-12-2007 16:20 от Алексей1153++ » Записан

Насколько я опытен? Достаточно, чтобы понимать, что дураков нельзя заставить думать по–другому, но недостаточно, чтобы отказаться от попыток это сделать.
(с) Артур Джонс
Pu
Большой босс

ru
Offline Offline
78


« Ответ #14 : 23-09-2004 06:21 » 

Да! так мы можем вызвать только функцию f() c любым количеством параметров, НО :!:  как вызвать любую функцию класса одним функтором?  :?:
Записан

Насколько я опытен? Достаточно, чтобы понимать, что дураков нельзя заставить думать по–другому, но недостаточно, чтобы отказаться от попыток это сделать.
(с) Артур Джонс
Pu
Большой босс

ru
Offline Offline
78


« Ответ #15 : 23-09-2004 06:22 » 

lapulya, спасибо за решение. Мне хотелось просто чтобы использовались функции-члены. Без всяких дополнительных наворотов и не более того. В книжке Effective STL как раз и описываются способ решения этого с помощью mem_fun(). Потому у мене непонятка и возникла. Да и функторами пространство имен глобал не охота было заваливть. Хотя есть идэя просто для своих использовать свой namespace. А еще попробовал и так -
Код:
class MyClass 
{
public:
int f(int a, int b, char c)
{
return 28;
}
class functor
{
int a;
int b;
char c;

public:
functor(int _a, int _b, char _c) : a(_a), b(_b), c(_c) {}
void operator () (MyClass * object)
{
object->f(a,b,c);
}
};
};

void main()
{
std::vector<MyClass *> v;

v.push_back(new MyClass);
v.push_back(new MyClass);
v.push_back(new MyClass);
v.push_back(new MyClass);
v.push_back(new MyClass);

std::for_each(v.begin(), v.end(), MyClass::functor(3,5,'n'));
}
тож работает  Улыбаюсь . Спасибки бальшие. Горизонты раздвинулись.  Ага .
« Последнее редактирование: 01-12-2007 16:23 от Алексей1153++ » Записан

Насколько я опытен? Достаточно, чтобы понимать, что дураков нельзя заставить думать по–другому, но недостаточно, чтобы отказаться от попыток это сделать.
(с) Артур Джонс
lapulya
Молодой специалист

ru
Offline Offline

« Ответ #16 : 23-09-2004 07:54 » 

то заяц, я к этому и клонил вот тут
Цитата
т.е. какой уровень универсальности интересует
независимость от типа объекта....
и вот еще
Цитата
.... с произвольными объектами, с произвольными функциями этих объектов, с произвольными типами параметров этих функций-мемберов.....
то что ты написал, как раз и демонстрирует выше сказанное
Код:
class MyClass 
{
public:
   int f(int a, int b, char c)
   {
      return 28;   
   }

};
 
namespace functors
{
   template<class t, class arg1, class arg2, class arg3>
   class functor
   {
      arg1 a;
      arg2 b;
      arg3 c;

   public:
      functor(arg1 _a, arg2 _b, arg3 _c) : a(_a), b(_b), c(_c) {}
      void operator () (t * object)
      {
         object->f(a,b,c);
      }
   };
}

int _tmain(int argc, _TCHAR* argv[])
{
   std::vector<MyClass *> v;

   v.push_back(new MyClass);
   v.push_back(new MyClass);
   v.push_back(new MyClass);
   v.push_back(new MyClass);
   v.push_back(new MyClass);

   std::for_each(v.begin(), v.end(), functors::functor<MyClass, int, int, char>(3,5,'n'));
   return 0;
}
это еще непредел.... тут у тебя идет завязка на количество параметров функции-члена И на СОБСТВЕННО ФУНКЦИЮ (в нашем примере это f), но можно переписать так, чтобы завязки на конкретную функцию не было, а была только на кол-во параметров. Ну то-есть просто написать шаблон аналогичный bind2nd и скажем для 55 параметров назвать его bind55ndи всего делов то... но избавится и от количества параметров невозможно
« Последнее редактирование: 01-12-2007 16:24 от Алексей1153++ » Записан

С уважением Lapulya
lapulya
Молодой специалист

ru
Offline Offline

« Ответ #17 : 28-09-2004 10:39 » 

Заяяяц ты меня слышишь.... Это опять я :oops:
вот тебе еще, это то, о чем я писал (функтор зависит ТОЛЬКО от количества параметров)
Код:
#include <vector>
#include <algorithm>

class Bar
{
public:
    int f(int a, int b, int c) { return a + b + c; }
};

class NOTBar
{
public:
    int NOTf(int a, int b, int c) { return a + b - c; }
};
 
template<class R, class T, class P1, class P2, class P3>
struct functor
{
R (T::*function)(P1, P2, P3);

P1 param1;
P2 param2;
P3 param3;

    explicit functor(R (T::*_function)(P1, P2, P3), P1 _param1, P2 _param2, P3 _param3) :
function(_function),
param1(_param1),
param2(_param2),
param3(_param3)
{}

    R operator()(T * p)
{
return (p->*function)(param1, param2, param3);
}
};

void main()
{
std::vector<Bar *> bars;
std::vector<NOTBar *> notbars;

bars.push_back(new Bar);
bars.push_back(new Bar);
std::for_each(bars.begin(), bars.end(), functor<int, Bar, int, int, int>(&Bar::f, 10,10,10));

notbars.push_back(new NOTBar);
notbars.push_back(new NOTBar);
std::for_each(notbars.begin(), notbars.end(), functor<int, NOTBar, int, int, int>(&NOTBar::NOTf, 10,10,10));
}
« Последнее редактирование: 01-12-2007 16:26 от Алексей1153++ » Записан

С уважением Lapulya
Pu
Большой босс

ru
Offline Offline
78


« Ответ #18 : 28-09-2004 12:52 » 

lapulya, спасибо Ага. Это класс.
Я правда поразобрался с библой Loki там функтор может содержать до 15 аргументов.
Если к твоему примеру добавить их списки типов, вот и получается все что надо.
Записан

Насколько я опытен? Достаточно, чтобы понимать, что дураков нельзя заставить думать по–другому, но недостаточно, чтобы отказаться от попыток это сделать.
(с) Артур Джонс
lapulya
Молодой специалист

ru
Offline Offline

« Ответ #19 : 05-10-2004 10:33 » new

заяц, привет...
Цитата
Я правда поразобрался с библой Loki там функтор может содержать до 15 аргументов.
Если к твоему примеру добавить их списки типов, вот и получается все что надо.
да я тут мог и 150 аргументов написать мне не трудно...
выглядеть будет страшно правда.... ну примерно вот так
Код:
template<class R, class T, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8 ...........> 
struct functor
{
   R (T::*function)(P1, P2, P3, P4, P5, P6, P7, P8........);

   P1 param1;
   P2 param2;
   P3 param3;
   P4 param4;
   P5 param5;
   P6 param6;
   P7 param7;
   P8 param8;
   ........

    explicit functor(R (T::*_function)(P1, P2, P3, P4, P5, P6, P7, P8, ........), P1 _param1, P2 _param2, P3 _param3, P4 _param4, P5 _param5, P6 _param6, P7 _param7, P8 _param8), .......... :
                  function(_function),
                  param1(_param1),
                  param2(_param2),
                  param3(_param3)
                  param4(_param4),
                  param5(_param5),
                  param6(_param6)
                  param7(_param7),
                  param8(_param8),
                  .............
   {}

    R operator()(T * p)
   {
      return (p->*function)(param1, param2, param3, param4, param5, param6, param7, param8, ..........);
   }
};
вот приблизительно так (можно и продолжить... но у меня чего то рука копипастить устала Отлично) ... думаю в локи приблизительно также...
кстати тут параллельная тема ну почти такая-же... называется чего-то примерно... "мастера шаблонов" или типа того. Ага
« Последнее редактирование: 01-12-2007 16:28 от Алексей1153++ » Записан

С уважением Lapulya
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines