我正在尝试使用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 :(得分:4)
sys
是一个非静态成员函数;它们的行为与普通函数不同,因为它们具有隐式this
参数。
可能的修复方法是:
(1)使用C ++ 11 lambda代替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
时构建它。
答案 1 :(得分:1)
您的move函数将sys作为参数传递,编译器会为此提供正确的语法。您可以在移动函数中交换sys以获取适当的lambda表达式,或使用bind。
http://en.cppreference.com/w/cpp/utility/functional/bind
http://www.cprogramming.com/c++11/c++11-lambda-closures.html