2014-12-22 9 views
3

Я пытаюсь вызвать внешнюю функцию (которая принимает функции как входы) внутри класса, предоставляя функции-члены класса как свои параметры. Мой код выглядит следующим образом:C++ вызов функции класса внутри другой функции

using namespace std; 
// This is my external function 
double integrate (double a, double b, int steps, double (*func)(double)){ 
    // code for integration using function pointer 
}; 

Class A 
{ 
    protected: 
     vector<double> to_data, from_data; 
     int data_size; 

    public: 
     A(); // constructor 

     double calculate_parameter(double t){ 
      // some class member function that makes use of other class members 
     }; 

     double get_result(double x){ 
      double sum = 0; 
     for (int i=0;i<data_size;i++){ 
      // this is basically what causes the error 
      sum = sum + integrate(to_data[i],from_data[i],1,calculate_parameter); 
     } 
}; 

} 

Однако, это показывает мне ошибку, что функция calculate_parameter не может быть преобразована. Я понял, как решить эту проблему, это изменить внешнюю функцию так, чтобы она также взяла объект класса. Есть ли способ сделать это без создания экземпляра нового объекта класса? Заранее спасибо!

ответ

8

Более общий подход заключается в отбросить эти функции 1970s указатели и использование технологии из этого тысячелетия:

#include <functional> 

double integrate (double a, double b, int steps, std::function<double(double)> f) 
{ 
    // ... 
} 

class A 
{ 
    double calculate_parameter(double t); 

    double get_result(double x) 
    { 
     using std::placeholders::_1; 

     double sum = 0; 
     for (int i = 0; i < data_size; i++) { 
      sum = sum + integrate(
       to_data[i], 
       from_data[i], 
       1, 
       std::bind(&A::calculate_parameter, this, _1) 
      ); 
     } 

     return sum; 
    } 
}; 

Это обеспечивает простой и легкий способ связать по существу любой вид функции и «запекать» указатель this для функций-членов самому функтору, не требуя магии на конечном call-сайте (то есть в пределах integrate, который буквально просто должен позвонить f!).


Еще более «современный» способ сделать это, чтобы обернуть вызов calculate_parameter в лямбда:

template <typename Callable> 
double integrate (double a, double b, int steps, Callable f) 
{ 
    // ... 
} 

class A 
{ 
    double calculate_parameter(double t); 

    double get_result(double x) 
    { 
     double sum = 0; 
     for (int i = 0; i < data_size; i++) { 
      sum = sum + integrate(
       to_data[i], 
       from_data[i], 
       1, 
       [this](double x) { return this->calculate_parameter(x); } 
      ); 
     } 

     return sum; 
    } 
}; 

Обратите внимание, что я заменил std::function<double(double)> с выведенным аргументом шаблона Callable; у вас нет , для этого нужно сделать, но это не означает, что вы не должны преобразовывать лямбда-to-std::function, когда вам это не нужно. (Лично я очень хотел быть в состоянии санкционировать, что f примет double и вернуть double, без необходимости полагаться на его использование, чтобы проверить это.)

+1

Спасибо! Это сработало отлично! – AnotherCodingEnthusiast

+2

@nurettin: «Самодовольство» ?? Какие?? Постарайтесь не быть таким грубым, спасибо. –

+1

довольно точный и лучший ответ –

-1

Эта функция calculate_parameter должна быть статической. Подробнее о функции объектов в Fuction Objects

Смежные вопросы