2014-11-26 1 views
2

Я пытаюсь использовать odeint (т. Е. Библиотека для решения дифференциальных уравнений) внутри класса, но я не мог. Мне действительно нужно поместить его в класс, чтобы я мог контролировать свой проект. Это ошибка, я получаю error C3867: 'robot::sys': function call missing argument list; use '&robot::sys' to create a pointer to memberвызов функции отсутствует список аргументов

и это мой код

#include <iostream> 
#include <boost/numeric/odeint.hpp> 

using namespace std; 
using namespace boost::numeric::odeint; 

/* The type of container used to hold the state vector */ 
typedef std::vector<double> state_type; 

class robot 
{ 
    double g, dt, t; 
    runge_kutta_dopri5<state_type> stepper; 

public: 
    state_type x; 

    robot() : x(2) 
    { 
     x[0] = 1.0; 
     x[1] = 0.0; 
     t = 0; 
     g = 0.15; 
     dt = 0.1; 
    } 

    void move(); 
    void sys(const state_type &x, state_type &dx, double t); 
}; 


void robot::move() 
{ 
    stepper.do_step(sys , x , t, dt); 
    t += dt; 
} 


void robot::sys(const state_type &x , state_type &dx , double t) 
{ 
    dx[0] = x[1]; 
    dx[1] = -x[0] - g*x[1]; 
} 



int main(int argc, char **argv) 
{ 
    robot Robo; 

    for (size_t i(0); i < 100; ++i){ 
     Robo.move(); 
    } 


    return 0; 
} 

Когда я пытаюсь решение, которое предложено в сообщении об ошибке, я получаю другую ошибку, которая

....\odeint\stepper\base\explicit_error_stepper_fsal_base.hpp(279): error C2064: term does not evaluate to a function taking 3 arguments

+0

Что такое 'g' в' robot :: sys'? Возможно, вы имели в виду 't'? Похоже, что ошибка находится в строке 'stepper.do_step (...)'. Узнайте больше о 'do_step' и как он используется? –

+0

Первым параметром 'do_step' должен быть объект функции. В зависимости от поддержки вашего компилятора lambdas вы можете использовать там лямбда, использовать 'bind' или написать отдельный класс функтора (так как ваш объект функции имеет состояние с' g'). –

+0

@Hohit Jain, я имею в виду 'g'. Это член данных класса робота. – CroCo

ответ

4

sys не является членом статической функции; они не ведут себя как обычные функции, потому что они имеют неявный параметр this.

Возможные исправления являются:

(1) С помощью C++ 11 лямбда а вместо sys:

void robot::move() 
{ 
    stepper.do_step([this](const state_type &x, state_type &dx, double t){ 
     dx[0] = x[1]; 
     dx[1] = -x[0] - g*x[1]; 
    }, x , t, dt); 
    t += dt; 
} 

(2) Держите sys и использовать std::bind или boost::bind:

void robot::move() 
{ 
    using namespace std::placeholders; 
    stepper.do_step(std::bind(&robot::sys, this, _1, _2, _3), x , t, dt); 
    t += dt; 
} 

(3) Используйте специально написанный функтор вместо sys:

struct System { 
    double g; 
    explicit System(double g) : g(g) {} 
    void operator()(const state_type &x , state_type &dx , double t) 
    { 
     dx[0] = x[1]; 
     dx[1] = -x[0] - g*x[1]; 
    } 
}; 

void robot::move() 
{ 
    stepper.do_step(System(g), x , t, dt); 
    t += dt; 
} 

Обратите внимание, что в этом случае вы можете иметь ваш класс хранить System объект вместо хранения g и построения его на каждом вызове move.

+0

большое вам спасибо. Я доволен вторым решением. – CroCo

1

Ваша функция перемещения передаёт sys как аргумент, и компилятор предлагает правильный синтаксис для этого. Вы можете поменять sys для соответствующего выражения лямбда в функции перемещения или использовать bind.

http://en.cppreference.com/w/cpp/utility/functional/bind

http://www.cprogramming.com/c++11/c++11-lambda-closures.html

+0

Я пробовал предложение, но оно вызывает еще одну ошибку. – CroCo

+0

Обновлен ответ. В основном - поместите ваш код sys в лямбда-выражение и передайте его как параметр в функцию do_step. –

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

  • Нет связанных вопросов^_^