Russian Qt Forum

Программирование => С/C++ => Тема начата: Sancho_s_rancho от Октябрь 10, 2010, 00:02



Название: std::accumulate передать метод класса
Отправлено: 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);

Но не статический метод класса передать не могу. Компилятор ругается. Куда копать?


Название: Re: std::accumulate передать метод класса
Отправлено: Sancho_s_rancho от Октябрь 10, 2010, 00:13
Сам спросил, сам ответил.
Или выносить функцию из класса или делать ее статической или использовать bind, которого в текущем стандарте ISO еще нет(в tr1 сидит), но есть в boost.


Название: Re: std::accumulate передать метод класса
Отправлено: sergey_ulyanov от Октябрь 10, 2010, 07:44
mem_fun (http://www.sgi.com/tech/stl/mem_fun_t.html)?


Название: Re: std::accumulate передать метод класса
Отправлено: Sancho_s_rancho от Октябрь 10, 2010, 08:56
mem_fun (http://www.sgi.com/tech/stl/mem_fun_t.html)?
В том примере функция без параметров. С параметрами у меня не срослось. Можете привести рабочий пример?


Название: Re: std::accumulate передать метод класса
Отправлено: m_ax от Октябрь 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;
}
 


Название: Re: std::accumulate передать метод класса
Отправлено: m_ax от Октябрь 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;
};