Russian Qt Forum
Ноябрь 24, 2024, 04:30 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: std::accumulate передать метод класса  (Прочитано 4190 раз)
Sancho_s_rancho
Гость
« : Октябрь 10, 2010, 00:02 »

Хочу сделать свой reduce в контейнере. Передать функцию просто:
Код:
double accum_sq(double sum_so_far, double x)
{
    return sum_so_far + x * x; //как пример
}

.... double sum_squares_xs
         = accumulate(xs.begin(), xs.end(), 0.0, accum_sq);

Но не статический метод класса передать не могу. Компилятор ругается. Куда копать?
Записан
Sancho_s_rancho
Гость
« Ответ #1 : Октябрь 10, 2010, 00:13 »

Сам спросил, сам ответил.
Или выносить функцию из класса или делать ее статической или использовать bind, которого в текущем стандарте ISO еще нет(в tr1 сидит), но есть в boost.
Записан
sergey_ulyanov
Гость
« Ответ #2 : Октябрь 10, 2010, 07:44 »

mem_fun?
Записан
Sancho_s_rancho
Гость
« Ответ #3 : Октябрь 10, 2010, 08:56 »

В том примере функция без параметров. С параметрами у меня не срослось. Можете привести рабочий пример?
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #4 : Октябрь 10, 2010, 10:58 »

Как вариант можно сделать так:

Код
C++ (Qt)
#include <iostream>
#include <functional>
#include <numeric>
#include <vector>
using namespace std;
 
class MyClass
{
public:
   double accum_sq(double sum_so_far, double x) {
       return sum_so_far + x * x;
   }
};
 
template <class T, typename U>
class Function
{
public:
   Function(T *t, U (T::*function)(U, U))
   {
       _obj = t;
       _function = function;
   }
 
   U operator()(const U &x, const U &y) {
       return (_obj->*_function)(x, y);
   }
private:
   T *_obj;
   U (T::*_function)(U, U);
};
 
 
int main () {
   vector<double> v(10, 1.0);
   double init = 50.0;
 
   MyClass m;
   Function<MyClass, double> func(&m, &MyClass::accum_sq);
 
   cout << "using custom class: ";
   cout << accumulate (v.begin(), v.end(), init, func );
   cout << endl;
 
   return 0;
}
 
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #5 : Октябрь 10, 2010, 15:21 »

Накатал тут небольшой класс по этому поводу:
Код
C++ (Qt)
template <class T, typename U>
class Function
{
public:
   Function(T *t, U (T::*function)(U, U))
   {
       _obj = t;
       _function1 = function;
       _index = 1;
   }
 
   Function(T *t, U (T::*function)(U, U) const)
   {
       _obj = t;
       _function2 = function;
       _index = 2;
   }
 
   Function(T *t, U (T::*function)(const U&, const U&))
   {
       _obj = t;
       _function3 = function;
       _index = 3;
   }
 
   Function(T *t, U (T::*function)(const U&, const U&) const)
   {
       _obj = t;
       _function4 = function;
       _index = 4;
   }
 
   U operator()(const U &x, const U &y) const {
       if (_obj) {
           if (_index == 1)
               return (_obj->*_function1)(x, y);
           if (_index == 2)
               return (_obj->*_function2)(x, y);
           if (_index == 3)
               return (_obj->*_function3)(x, y);
           if (_index == 4)
               return (_obj->*_function4)(x, y);
       }
       return x+y;
   }
 
private:
   T *_obj;
   U (T::*_function1)(U, U);
   U (T::*_function2)(U, U) const;
   U (T::*_function3)(const U&, const U&);
   U (T::*_function4)(const U&, const U&) const;
   int _index;
};
 
« Последнее редактирование: Октябрь 10, 2010, 15:25 от m_ax » Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.099 секунд. Запросов: 23.