Passing a member function pointer(s) - c++

My situation is following, I have two different bisection functions what will be called at some point in my code. Basically some function calls Bisection2 and this function calls either the passed function or it passes the function pointer to Bisection function.
in header I have
std::vector<double> F();
double F1(double m1, double m2);
double F2(double m1, double m2);
typedef double (MyClass::*MyClassFn)(double,double);
double Bisection(MyClassFn fEval,double min, double max,std::vector<double> args);
bool Bisection2(MyClassFn fEval1,MyClassFn fEval2,double xmin, double xmax, double ymin, double ymax,double *ax, double *ay,std::vector<double> args);
And my bisection functions look like this. I didn't include all the code because it's not necessary.
double MyClass::F1(double m1, double m2) {
m_m1 = m1;
m_m2 = m2;
F();
return m_my;
}
double MyClass::F2(double m1, double m2) {
m_m1 = m1;
m_m2 = m2;
F();
return m_mx;
}
double MyClass::Bisection(MyClass fEval,double min, double max,std::vector<double> args)
{
// Setting a lot of stuff here, including auxiliary and leftvalue...
MyClass *pObj = new MyClass(-1);
leftvalue = pObj->*fEval(auxiliary, left);
ightvalue = pObj->*fEval(auxiliary, right);
// Comparing and setting values here etc.
}
bool MyClass::Bisection2(MyClassFn fEval1,MyClassFn fEval2,double xmin, double xmax, double ymin, double ymax,double *ax, double *ay,std::vector<double> args)
{
// Setting some values here but these have nothing to do with the problem.
double yl;
double leftvalue, rightvalue, middlevalue;
MyClass *pObj = new MyClass(-1);
// Setting some values here but these have nothing to do with the problem.
std::vector <double> arg;
// pushing some values
yl = Bisection(fEval2,ymin,ymax,arg); // Here is the first way how I need to pass fEval2 to Bisection function.
arg.clear();
if(isnan(yl))
{
return M_NAN;
}
leftvalue = pObj->fEval1(xl, yl); // And here is the second way how I need to use fEval1.
//.....
}
And then I have basically a function what calls
`Bisection2(F1,F2, m_m2,0.0, 0.0, m_max2, &m_mu1, &m_mu2,args);
The Bisection2(...) call may be incorrect at the moment because I've changed the functions a lot since this worked last time. Last time I basically called F1 and F2 function pointers directly inside the functions instead of fEval's but I'm quite sure it was incorrect way after all even thought it seemed to work somehow.
Now leftvalue = pObj->*fEval(auxiliary, left); causes compiling errors:
error: must use ‘.*’ or ‘->*’ to call pointer-to-member function in ‘fEval (...)’, e.g. ‘(... ->* fEval) (...)’
I've tried to see help from here http://www.parashift.com/c++-faq-lite/pointers-to-members.html#faq-33.2
and also checked maybe different solved problems in these forums but still can't figure out what I'm doing wrong.
Thank you.

As the error message says, you need parentheses. This is because the function call has higher precedence than the ->* operator:
leftvalue = (pObj->*fEval)(auxilary, left);
^ ^
Also, you almost certainly shouldn't be using new here; you can fix the memory leaks using automatic storage:
MyClass obj(-1);
leftvalue = (obj.*fEval)(auxiliary, left);

This is simply a matter of priority :
Instead of doing pObj->*fEval(aux, left), just do (pObj->*fEval)(aux, left)

Related

How do I re-assign a function name in C++

I have a problem in C++ that is similar to this example problem. In this case I have two member-functions that have an identical interface. Based on the information in a string passed to the super function, I would like to assign one of the two member functions to the variable class_func. Is there a way to do this?
// test.hpp
class TestClass
{
public:
double master_function(double a, double b, std::string func_name);
private:
double add(double a, double b);
double subtract(double a, double b);
};
// test.cpp
double TestClass::master_function(double a, double b, std::string func_name)
{
if (func_name == std::string("Add") const auto& class_func = add;
else const auto& class_func = subtract;
return class_func(a, b);
}
// =========================================================================
double TestClass::add(double a, double b)
{
return a + b;
}
// =========================================================================
double TestClass::subtract(double a, double b)
{
return a - b;
}
In other words, I am trying to assign the member-function add or subtract to the name class_func, so the code underneath the if statement in master_function can be uniform regardless of which function the user wants to use. In the form shown below I get the error Reference to non-static member function must be called out, but I am not totally sure what this means or how to fix it. In addition, I am using a C++17 compiler, so if there is a modern approach that works best with C++17 I would be interested in learning it.
The term you are looking for is member function pointer, but we can do without explicitly specifying that type. The problem with your code is not only in the way you try to refer to a member function (that would be &TestClass::add), but also that you create those aliases in a nested scope (under if/else), meaning they won't be visible in the return statement.
The simplest change is this:
auto class_func = &TestClass::add; // pick one default
if (func_name == "Subtract")
{
class_func = &TestClass::subtract;
}
else
{
assert(func_name == "Add"); // optional
}
return class_func(a, b);
This works because the add and subtract functions have the exact same type:
double (TestClass::*)(double a, double b)
But yeah, why are those functions not static? They do not work with a class' instance. Make them static and the above will still work, just note that the type of class_fun will be a simple function pointer:
double (*)(double a, double b)
Now that you know the types, you could change this in a way that does not privilege one function before the other in the code:
decltype(&TestClass::add) class_func = nullptr;
if (func_name == "Add")
{
class_func = &TestClass::add;
}
else if (func_name == "Subtract")
{
class_func = &TestClass::subtract;
}
assert(class_func != nullptr);
return class_func(a, b);
As mentioned in the comments, as that if-else chain starts to get longer, it makes more and more sense to use a (hash)map between strings and function pointers.

boost::odeint called within member class

this is a personal project I've been working on and I can't figure out what's going on here (just learning C++). I found answers to very similar problems, but I can't seem to execute the solution. Here is my code with some of the unimportant bits trimmed out:
#include <iostream>
#include <cmath>
#include <complex>
#include <boost/array.hpp>
#include <boost/numeric/odeint.hpp>
#include <gsl/gsl_roots.h>
class Riemann
{
public:
// constructor
Riemann(double leftP, double rightP, double leftrho, double rightrho, \
double leftvx, double rightvx, double leftvy, double rightvy, double gam);
double PL,PR,rhoL,rhoR,vxL,vxR,vyL,vyR,gamma;
// function prototypes
double shockvelocity(double Pg, int sign);
double rarefactionvelocity(double Pg, int sign);
void RfODE(const boost::array<double,6> &vrhovt, \
boost::array<double,6> &dvrhovtdp, double t);
// ~Riemann();
};
Riemann::Riemann(double leftP, double rightP, double leftrho, double rightrho, \
double leftvx, double rightvx, double leftvy, double rightvy, double gam){
// constructs Riemann public variables
}
double Riemann::shockvelocity(double Pg,int sign){
// calculate a shock velocity, not important here...
}
void Riemann::RfODE(const boost::array<double,6> &vrhovt, \
boost::array<double,6> &dvrhovtdp, double t){
// calculates the ODE I want to solve
}
double Riemann::rarefactionvelocity(double Pg, int sign){
double dpsize=0.00001;
double P,rho,vx,vy,vtest;
//
boost::array<double,6> vrhovt = {vx,rho,vy,double(sign),P,gamma}; // initial conditions
boost::numeric::odeint::integrate(std::bind(&Riemann::RfODE,std::ref(*this),std::placeholders::_1,
std::placeholders::_2, std::placeholders::_3),vrhovt,P,Pg,dpsize);
std::cout<<"vRarefaction="<<vrhovt[0]<<std::endl;
return vrhovt[0];
}
double FRiemann(double Pg, void* Riemannvalues){
Riemann* Rvals = (Riemann*)Riemannvalues;
// calls on Riemann::rarefactionvelocity at some point
}
int main(){
double PL= 1000.0;
double PR= 0.01;
double rhoL= 1.0;
double rhoR= 1.0;
double vxL= 0.0;
double vxR= 0.0;
double vyL= 0.0;
double vyR= 0.0;
double gam = 5.0/3.0;
// calls FRiemann to get a root
}
What's happening is the code is going through, calling Riemann::rarefactionvelocity just fine, but for some reason RfODE is never executed (ex. print statements in this function never execute) and the value for vrhovt[0] returned is of course the value it began with, vx. No compiler errors, either (using gcc 4.8.1 and -std=c++11 and -O2 tags) This is very strange because I've tested the rarefaction-specific functions on their own (outside of the Riemann class) and they work -- the problem seems to be that they're in this class. Given how Riemann solvers work, though, I had my reasons for making a class out of these functions and really would like to find a way to make this work without doing a massive rewrite and changing the class structure.
Any help is much appreciated! Thank you! : )
It might be possible that P is not initialized correctly. At least I don't see it in your code. P needs to be smaller than PG otherwise your are already behind your the end of the integration.
Also, don't use bind, use a lambda instead. I think bind is somehow obsolete in C++11/C++14. It might be possible that bind doesn't get the references correct.
double Riemann::rarefactionvelocity(double Pg, int sign)
{
// ...
// not tested
using namspace boost::numeric::odeint;
integrate( [this](auto const& x, auto &dxdt ,auto t ) {
this->RfODE(x, dt, t); } ,vrhovt,P,Pg,dpsize);
}

Using the same double in different functions

I have two functions which use the same doubles ie like
in the .h I declare
class MyClass : {
public :
double arg1, arg2;
void getVarA(double a, double b);
void getVarB(double a, double b);
void Reset();
}
and in my .C I have something like
void MyClass::Reset(){
arg1 = 0.0f;
arg2 = 0.0f;
}
void MyClass::getVarA(double a, double b){
arg1+=2*a;
arg2+=2*b;
return arg1-arg2;
}
void MyClass::getVarB(double a, double b){
arg1+=2+a;
arg2+=2+b;
return arg1-arg2;
}
The problem is that in principle I want to create a copy of arg1,arg2 each one taking values in each function (ie in each function to be possible to take different values) so that arg1,arg2 dont "speak" between the two different functions and whenever I change the arg1 in getVarA function not to commute with the arg1 in getVarB function.
Sorry, probably my example is poorly phrased but I am just newbie..
thanks
Make your variables arg1, arg2 as function local variables.
void MyClass:getVarA(double a, double b) {
double arg1, arg2;
arg1+=2*a;
arg2+=2*b
return arg1-arg2
}
void MyClass:getVarB(double a, double b) {
double arg1, arg2;
arg1+=2+a;
arg2+=2+b
return arg1-arg2
}
They will become different variables. None of changes made in getVarA arg1, arg2 will affect arg1, arg2 from getVarB
EDIT
According to #harper comment, it is strongly recommended to avoid uninitialized variables. You can't assume initial value of arg1 and arg2 variables. Your should explicit set initial value
double arg1 = 0.0;
double arg2 = 0.0;
"The problem is that in principle I want to create a copy of arg1,arg2"
You can do exactly that:
void MyClass::getVarA(double a, double b)
{
double arg1Copy = arg1;
double arg2Copy = arg2;
arg1Copy+=2*a;
arg2Copy+=2*b;
return arg1Copy-arg2Copy;
}
Now arg1 and arg2 are not modified by your method. In fact you can even declare your method as const to inform the compiler that you do not want the data members to actually be modified by your method.
This answer is based on the following interpretation of your question:
Each of the getVar functions is supposed to remember something about previous calls. The value returned from a function call is supposed to change based on what calls were made to that function in the past. For example, if you ran this code, x1 and x2 would have different values:
MyClass mc;
double x1 = mc.getVarA(1,1);
double x2 = mc.getVarA(1,1);
If you want x1 and x2 to have different values (because the first call is supposed to change what values are used in the second call), then this answer is appropriate. If you want x1 and x2 to have the same value (because you don't want getVarA to remember anything about previous function calls), nnesterov's suggestion to use local variables is a better answer than this one.
You want what is remembered about calls to getVarA to be independent from what is remembered about calls to getVarB.
With that in mind, here's the .h:
class MyClass {
public :
double _varA1, _varA2;
double _varB1, _varB2;
MyClass();
double getVarA(double a, double b);
double getVarB(double a, double b);
void Reset();
};
and here's the .c:
MyClass::MyClass(){
Reset();
}
void MyClass::Reset(){
_varA1 = 0.0;
_varA2 = 0.0;
_varB1 = 0.0;
_varB2 = 0.0;
}
double MyClass::getVarA(double a, double b){
_varA1 += 2*a;
_varA2 += 2*b;
return _varA1 - _varA2;
}
double MyClass::getVarB(double a, double b){
_varB1 += 2+a;
_varB2 += 2+b;
return _varB1 - _varB2;
}
Things to notice:
Each of the two get functions has its own set of instance variables. That way you can change one function's data without changing the other function's data.
The constructor calls Reset() so that the variables are initialized when you first create an instance of the class. That way you can predict what will happen the first time you call each get function.
The return type of the get functions has been changed to double, to match the implementation.

Undefined behavior when passing C++ objects to C routine

Update
I found that if I pass by reference in the constructor, then it fix the problem in A.cpp!
i.e. InfoPass(vector<double> &arg0, vector<double> &arg1...), but what's the reason?
Update
Basically I want to call some c code from c++.
as explained in the c mannual, to avoid using gloabal variables, a "void *fdata" is provided to get addtional information, if not any, it's pointed to NULL.
int f(unsigned ndim, unsigned npts, const double *x, void *fdata,
unsigned fdim, double *fval);
Now I need to pack some c++ objects and pass to "f" through this *fdata argument, the way I could think of is to define a class "InfoPass", and pass it to the c routine.
my c++ snippet (example A.cpp and B.cpp, A doesn't work properly while B is OK):
// Example A.cpp
#include "cubature.h" // the c library called cubature
#include "extern_cpp_class.hpp" //
class InfoPass
{
public:
extern_cpp_class obj1;
extern_cpp_class obj2;
extern_cpp_class obj3;
double arr[3];
InfoPass(vector<double>arg0, vector<double>arg1, vector<double>arg2, vector<double>arg3)
: obj1{arg0, arg1}, obj2{arg0, arg2}, obj3{arg0, arg3} {}
};
// the declaration of int f() and cubature() below are in the c code
int f(unsigned ndim, const double *x, void *fdata, unsigned fdim, double *fval);
int main() {
/*** do something ***/
InfoPass cubpass{arg0, arg1, arg2, arg3}; // initialize
cubature(2, f, &cubpass, 2, xmin, xmax, 1e5, 0, 1e-5, ERROR_PAIRED, OUTPUT, &err);
/*** process with output ***/
}
int f(unsigned ndim, const double *x, void *fdata, unsigned fdim, double *fval)
{
InfoPass *fcubpass=static_cast<InfoPass*>(fdata);
/*** do things with fcubpass.obj1, .obj2 ... ***/
}
Now, I can compile(gcc) and run example A, strangely, there are undefinded behaviors, sometimes it gives NaN, sometimes gives very crazy numbers...
However, if instead I do in the following way (Example B, use pointers to class) then use "new" in f, it works fine! wondering why? since I prefer the Example A to B in which I need to alway "new" somthing...
// Example B.cpp
class InfoPass
{
public:
extern_cpp_class *obj1=NULL;
extern_cpp_class *obj2=NULL;
extern_cpp_class *obj3=NULL;
double arr[3];
~InfoPass(){
delete obj1;
delete obj2;
delete obj3;
}
}
int main() {
/*** do something ***/
InfoPass cubpass; // declare
cubpass.obj1 = new extern_cpp_class(arg0,arg1);
cubpass.obj2 = new extern_cpp_class(arg0,arg2);
cubpass.obj3 = new extern_cpp_class(arg0,arg3);
cubature(2, f, &cubpass, 2, xmin, xmax, 1e5, 0, 1e-5, ERROR_PAIRED, OUTPUT, &err);
/*** process with output ***/
}
int f(unsigned ndim, const double *x, void *fdata, unsigned fdim, double *fval)
{
InfoPass *fcubpass=static_cast<InfoPass*>(fdata);
/*** do things with fcubpass->obj1, .obj2 ... ***/
}
Just a shot in the dark here.
What do extern_cpp_class objects do with their initialization parameters? If they take and store their vector arguments as references, you'd run into trouble with the original A.cpp since the arguments are temporary copies that are destroyed — invalidating the references — after cubpass's constructor is finished executing. Switching to passing references would fix this by ensuring that the extern_cpp_class objects receive references to vectors created in main that (presumably) remain valid until the program exits (or at least until you're done working with cubpass). In B.cpp, the constructors already get references to such vectors, hence no problems.
Since f should be the Callback function that is called by C-code it should use c's calling convention.
But since you declare and define it in cpp it uses another calling convention.
So maybe the parameter passing somehow goes wrong.
Try adding extern "C" in front of the declaration of f.
But this obviously does not satisfactorily explain, why one of your examples does work.
Could you change the initialization list in your InfoClass constructor to use parenthesis instead of curly braces?
obj1(arg0, arg1), obj2(arg0, arg2), obj3(arg0, arg3)
P.S. I would have posted this as a comment, but I dont have the reputations yet.

How to guard against function arguments being passed in the wrong order?

Say I have a C++ function that looks like this:
double myfunction(double a, double b) {
// do something
}
Which I then call like this:
double a = 1.0;
double b = 2.0;
double good_r = myfunction(a, b);
double bad_r = myfunction(b, a); // compiles fine
I would like to make sure that a and b are never provided in the wrong order.
What is the best way to ensure this in C++?
Other languages allow named parameters, like this:
double good_r = myfunction(a=a, b=b);
double bad_r = myfunction(a=b, b=a); // mistake immediately obvious
double bad_r = myfunction(b=b, a=a); // compiles fine
Or perhaps the problem can be partly solved using types, i.e.
double my_type_safe_function(a_type a, b_type b) {
// do something
}
a_type a = 1.0;
b_type b = 2.0;
double good_r = myfunction(a, b);
double bad_r = myfunction(b, a); // compilation error
EDIT: A couple of people have asked what I mean by the "wrong order." What I mean is that, in real code a and b have some significance. For example, the arguments might instead be height and width. The difference between them is very important for the function to return the correct result. However, they are both floats and they both have the same dimensions (i.e. a length). Also, there is no "obvious" order for them. The person writing the function declaration may assume (width, height) and the person using the function may assume (height, width). I would like a way to ensure this doesn't happen by mistake. With two parameters it is easy to be careful with the order, but in a large project and with up to 6 arguments mistakes creep in.
Ideally I would like the checks to be done at compile time, and for there to be no performance hit (i.e. at the end of the day they are treated as plain old floats or whatever).
How about this:
struct typeAB {float a; float b; };
double myfunction(typeAB p) {
// do something
return p.a - p.b;
}
int main()
{
typeAB param;
param.a = 1.0;
param.b = 2.0;
float result = myfunction(param);
return 0;
}
Of course, you can still mess up when you assign your parameter(s) but that risk is hard to avoid :)
A variant is to have one struct per "new" type, and then make them go away in optimized builds using macros.
Something along these lines (only slightly tested, so it could be way off):
#define SAFE 0
#if SAFE
#define NEWTYPE(name, type) \
struct name { \
type x; \
explicit name(type x_) : x(x_) {}\
operator type() const { return x; }\
}
#else
#define NEWTYPE(name, type) typedef type name
#endif
NEWTYPE(Width, double);
NEWTYPE(Height, double);
double area(Width w, Height h)
{
return w * h;
}
int main()
{
cout << area(Width(10), Height(20)) << endl;
// This line says 'Could not convert from Height to Width' in g++ if SAFE is on.
cout << area(Height(10), Width(20)) << endl;
}
I think you already provided the easiest solution, using types.
One alternative could be using a builder class and method chaining.
Like:
class MyfunctionBuilder {
MyFunctionBuilder & paramA(double value);
MyFunctionBuilder & paramB(double value);
double execute();
(...)
}
Which you would use like this:
double good_r = MyFunctionBuilder().paramA(a).paramB(b).execute();
But this is a lot of extra code to write!
What is the "wrong order" actually? In this example of yours
double myfunction(double a, double b) {
// do something
}
double a = 1.0;
double b = 2.0;
double good_r = myfunction(a, b);
double bad_r = myfunction(b, a);
how do you actually want to know if this is the right order? What if the variables would be named "quapr" and "moo" instead of "a" and "b"? Then it would be impossible to guess whether the order is right or wrong just by looking at them.
With this in mind, you can do at least two things. First, is to give meaningfull names to the arguments, e.g.
float getTax( float price, float taxPercentage )
instead of
float getTax( float a, float b )
Second, do the necessary checks inside:
float divide( float dividend, float divisor )
{
if( divisor == 0 )
{
throw "omg!";
}
}
It is possible to do more complex checks, such as making a functor, and setting it's parameters explicitly, but in most of the cases that just complicates things without much benefit.