I am quite new in C++ programming (but much more used to IDL and Python). I am actually trying to re-write a code that I have already written in IDL into C++, to improve its efficiency. In my project, I wish to call a function within a class, from another class. Below, I copied what I think is the essential part of the code required to understand the problem. However, I simplified it in order to improve its clarity.
When compiling with g++, I obtain the following error:
MALA.cpp: In member function ‘void MALA::update_position_MH(Model_def*, Data*, Config*, int)’:
MALA.cpp:277:52: error: no matching function for call to ‘Model_def::call_model(Data&)’
propos_model=(*model_class).call_model(*data_struc); // PROBLEM HERE! TO DEBUG!
^
In file included from MALA.h:13:0,
from MALA.cpp:29:
model_def.h:34:12: note: candidate: Eigen::VectorXd Model_def::call_model(Data*)
VectorXd call_model(Data *data_struc); // call a model using its name
^
model_def.h:34:12: note: no known conversion for argument 1 from ‘Data’ to ‘Data*’
What I do not understand is that the code compiles without errors if I comment the line (see at the very end of the given code):
propos_model=(*model_class).call_model(*data_struc); // PROBLEM HERE!
But then, why I do not get an error as well for the line:
vars_new=new_prop_values((*model_class).vars, m); // This works fine
What am I doing wrong when passing the structure 'Data' as an argument of the function call_model?
Here is the simplified code, spread in different files:
This is the model_def.h (simplified)
#include <Eigen/Dense>
#include <string>
#include "config.h"
#include "data.h"
class Model_def{
string model_name;
bool relax[];
int plength[];
VectorXd cons;
long Ncons, Nvars, Nparams;
string vars_names[];
string cons_names[];
string params_names[];
public:
Model_def(string m_name, bool rlx[], int plgth, VectorXd params_in, string params_in_names); // The constructor
Eigen::VectorXd params;
Eigen::VectorXd vars;
Eigen::VectorXd call_model(Data *data_struc);
};
This is the model_def.cpp (simplified)
#include <Eigen/Dense>
#include <iostream>
#include <iomanip>
#include "model_def.h"
Eigen::VectorXd Model_def::call_model(Data *data_struc){
bool passed=0;
if(model_name == "Model_MS_Global"){
passed=1;
return Model_MS_Global(params, plength, (*data_struc).x); // This function is in a dedicated cpp file (not shown here)
}
// Other things happening...
}
This is the data.h
#include <Eigen/Dense>
#include <string>
struct Data{
Eigen::VectorXd x;
Eigen::VectorXd y;
long Nx; // Ny is not checked but should be as long as x
string xlabel[];
string ylabel[];
};
This is the MALA.h (simplified)
#include <Eigen/Dense>
#include <string>
#include "model_def.h"
class MALA{
private:
int seed; // to generate random numbers
double epsilon1;
Eigen::MatrixXd epsilon2;
double A1;
double delta;
double delta_x;
public:
void update_position_MH(Model_def *model_class, Data *data_struc, Config *cfg_class, int m);
};
This is the MALA.cpp (simplified)
void MALA::update_position_MH(Model_def *model_class, Data *data_struc, Config *cfg_class, int m){
VectorXd vars_new;
double* u=uniform_01(1, &seed ); // Generate uniform random number between 0 and 1
VectorXd propos_model;
if((*cfg_class).proposal_type == "Random"){
vars_new=new_prop_values((*model_class).vars, m); // This works fine
}
propos_model=(*model_class).call_model(*data_struc); // PROBLEM HERE!
}
data_struc is a pointer, and call_model wants a pointer, so you just pass it directly. Putting a * in front "dereferences" it and makes it not a pointer anymore.
propos_model=(*model_class).call_model(data_struc);
Or, a bit better
propos_model = model_class->call_model(data_struc);