I am curious about how to call function pointer in a map structure. Here is the details:
#include<iostream>
#include<map>
#include<vector>
#include<string.h>
using namespace std;
class FuncP;
typedef int(FuncP::*func) (int, int);
class FuncP
{
public:
map<int, func> fmap;
map<int, string> fstring;
public:
FuncP(){}
void initial();
int max(int x, int y);
int min(int x, int y);
int call(int op, int x, int y)
{
return (this->*fmap[op])(x, y);
}
};
void FuncP::initial()
{
fmap[0] = &FuncP::max;
fmap[1] = &FuncP::min;
fstring[0] = "fdsfaf";
}
int FuncP::min(int x, int y)
{
return (x<y)?x:y;
}
int FuncP::max(int x, int y)
{
return (x<y)?y:x;
}
int main()
{
func h = &FuncP::max;
FuncP *handle = new FuncP();
handle->initial();
cout<< handle->call(0, 1, 4); //1
cout<< (handle->FuncP::*fmap)[0](1,5); //2
return 0;
}
For the number 2 (handle->FuncP::*fmap)0; The compiler gives a error:
‘fmap’ was not declared in this scope
I am not sure why it happened. What the difference of the number 1 and 2 call methods?
As commented by Piotr, a correct way would be
(handle->*(handle->fmap[0]))(1, 5);
Explanation:
handle->fmap[0] gives you the function pointer. To call it, you need to dereference it, giving *(handle->fmap[0]) (parentheses optional)
and call it on the respecting object (handle), leaving us with the expression above.
This is essentially the same as your above statement (this->*fmap[op])(x, y) except of handle->fmap[0]instead offmap[op].
Related
I am trying to avoid this repetitive code by writing a template function.
#include <algorithm>
class X {
public:
void get_amin(double *a){}
void set_amin(double a){}
void get_bmin(double *b){}
void set_bmin(double b){}
//...many pairs like above
};
int main(){
X *x1 = new X;
X *x2 = new X;
//code that will be repeated
{
double x1_amin;
x1->get_amin(&x1_amin);
double x2_amin;
x2->get_amin(&x2_amin);
x1->set_amin(std::min(x1_amin, x2_amin));
}
//repeatation
{
double x1_bmin;
x1->get_bmin(&x1_bmin);
double x2_bmin;
x2->get_bmin(&x2_bmin);
x1->set_bmin(std::min(x1_bmin, x2_bmin));
}
//
delete x1;
delete x2;
}
Now my attempts are below. It seems I am able to write the template but not able to use it. Other posts at stack overflow mostly focus on how to write the template. Also I could not find an example where a class member function is used.
#include <algorithm>
#include <functional>
class X {
public:
void get_amin(double *a){}
void set_amin(double a){}
void get_bmin(double *b){}
void set_bmin(double b){}
//...many pairs like above
};
template <typename F11,typename F12, typename F2>
void templatisedFunction(F12 f11,F12 f12,F2 f2)
{
double x1_amin;
f11(&x1_amin);
double x2_amin;
f12(&x2_amin);
f2(std::min(x1_amin, x2_amin));
}
int main(){
X *x1 = new X;
X *x2 = new X;
//templatisedFunction(x1->get_amin,x2->get_amin,x1->set_amin);
//templatisedFunction(x1->get_amin(double*),x2->get_amin(double*),x1->set_amin(double));
//templatisedFunction<x1->get_amin(double*),x2->get_amin(double*),x1->set_amin(double)>();
//templatisedFunction<x1->get_amin,x2->get_amin,x1->set_amin>();
std::function<void(X*)> memfun(&X::get_amin);//not sure here
//templatisedFunction<x1->get_amin,x2->get_amin,x1->set_amin>();
//
delete x1;
delete x2;
}
void (X::*getf)(double *) and void (X::*setf)(double) are the function signatures for the two pointer to member function that you need.
Using C++11:
int main()
{
X x1;
X x2;
auto lamb = [&](void (X::*getf)(double *), void (X::*setf)(double))
{
double x1_amin;
(x1.*getf)(&x1_amin);
double x2_amin;
(x2.*getf)(&x2_amin);
(x1.*setf)(std::min(x1_amin, x2_amin));
};
lamb(&X::get_amin, &X::set_amin);
lamb(&X::get_bmin, &X::set_bmin);
return 0;
}
You can use pointers to member functions to reduce repetition:
void set_min(X &x1, X &x2, void (X::*get_min)(double *), void (X::*set_min)(double)) {
double x1_amin;
(x1.*get_min)(&x1_amin);
double x2_amin;
(x2.*get_min)(&x2_amin);
(x1.*set_min)(std::min(x1_amin, x2_amin));
}
to be used like this:
set_min(*x1, *x2, &X::get_amin, &X::set_amin);
set_min(*x1, *x2, &X::get_bmin, &X::set_bmin);
If you have many pairs you could go even further and use a loop:
std::pair<void (X::*)(double *), void (X::*)(double)> get_set_pairs[] = {
{&X::get_amin, &X::set_amin},
{&X::get_bmin, &X::set_bmin},
};
for (auto &get_set_pair : get_set_pairs){
set_min(*x1, *x2, get_set_pair.first, get_set_pair.second);
}
I wrote a simple class that performs basic arithmetic operations using a method that receives an index and two values to compute.
The index indicates which operation to perform in a table that contains pointers to functions.
Here is my code:
#include <iostream>
using namespace std;
class TArith
{
public:
static const int DIV_FACTOR = 1000;
typedef int (TArith::*TArithActionFunc)(int,int);
struct TAction
{
enum Values
{
Add,
Sub,
count,
};
};
int action(TAction::Values a_actionIdx, int a_A, int a_B)
{
return ( this->*m_actionFcns[a_actionIdx] )(a_A,a_B);
}
private:
int add(int a_A, int a_B)
{
return a_A + a_B ;
}
int sub(int a_A, int a_B)
{
return a_A - a_B ;
}
static TArithActionFunc m_actionFcns[TAction::count];
int m_a;
int m_b;
};
TArith:: TArithActionFunc TArith:: m_actionFcns[TAction::count] = {
TArith::add,
TArith::sub
};
void main(void)
{
TArith arithObj;
int a=100;
int b=50;
for(int i = 0 ; i <TArith::TAction::count ; ++i)
{
cout<<arithObj.action( (TArith::TAction::Values)i,a,b )<<endl;
}
cout<<endl;
}
Compiler says:
'TArith::add': function call missing argument list; use '&TArith::add' to create a pointer to member
'TArith::sub': function call missing argument list; use '&TArith::sub' to create a pointer to member
why do I need to use the & symbol?
TArith:: TArithActionFunc TArith:: m_actionFcns[TAction::count] = {
TArith::add,
TArith::sub,
TArith::mul,
TArith::div
};
Correct syntax for a pointer to a member function f of a class C is &C::f. You're missing the leading &.
Try:
TArith:: TArithActionFunc TArith:: m_actionFcns[TAction::count] = {
&TArith::add,
&TArith::sub,
&TArith::mul,
&TArith::div
};
i want to take an input from c++ function and return it to the main function
, i've already tried to do it but the function returns zero , any idea ?
#include<iostream>
using namespace std;
int input( int x);
int main()
{
int number;
input(number);
cout<<number;
}
int input (int x)
{
cin>>x;
return x;
}
you need to pass by reference
void input (int & x)
{
cin>>x;
}
or use the return value
int main()
{
int number;
number = input();
cout<<number;
}
int input ()
{
cin>>x;
return x;
}
You can change your function to make it take x by reference:
void input (int& x)
{
cin>>x;
}
This way, you don't even need to return x, because your function will update its value as it is passed by reference.
So, let's get it from the begining :
It any function, all its variables are temporary and only accessible in this function's scope unless you use a pointer or a reference(c++ only)
So what happen when you call your function is that a copy of number's is created into x
Also, the return statement of a function is used to... return values! Yeah, weird uh?
So actually you don't even need to send any parameter to your function and just take its result :
#include<iostream>
using namespace std;
int input();
int main()
{
int number = input(); // Takes what the return statement gives
cout<<number;
}
int input ()
{
int x;
cin>>x;
return x;
}
Here's another way by using c++'s references :
#include<iostream>
using namespace std;
void input( int& x);
int main()
{
int number;
input(number);
cout<<number;
}
int input (int& x)//Takes number's address
{
cin>>x;
}
I have written this program but it doesn't work. It gives an error that x and y was not declared and expected primary expression before int on line 17.
#include<iostream>
using namespace std;
class shapes
{
int width, height;
public:
int getvalue();
void decideshape(int l, int b);
};
main()
{
cout<<"to find what type of shape you have input the measurements"<<endl;
shapes toy;
toy.getvalue();
toy.decideshape();
}
int shapes::getvalue()
{
int l, b;
cout<<"length = ";
cin>>l;
cout<<"breath = ";
cin>>b;
}
void shapes::decideshape(x, y)
{
if(x==y)
cout<<"This is square"<<endl;
else
cout<<"This is rectangle"<<endl;
}
how should i return 2 values from function getvalue
Arguments are required to have types in C++. Write your definition of shapes::decideshape as
void shapes::decideshape(int x, int y)
You don't return a value from shapes::getvalue.
You pass too few (actually none) parameters to shapes::decideshape. Two ints are expected to be supplied.
You need to tell the compiler what a function returns explicitly. Add the int return value to main.
You are missing the type of x and y in the parameter list:
void shapes::decideshape(int x, int y)
#include <iostream>
using namespace std;
template<class Type>
void Knapsack(Type *v,int *w,int c,int n,Type **m)
{
int i,j;
int jMax=max(w[n]-1,c);
for(j=0;j<=jMax;j++)
m[n][j]=0;
for(j=w[n];j<=c;j++)
m[n][j]=v[n];
for(i=n-1;i>1;i--)
{
for(j=0;j<=w[i]-1;j++)
m[i][j]=m[i+1][j];
for(j=w[i];j<=c;j++)
{
m[i][j]=max(m[i+1][j],m[i+1][j-w[i]]+v[i]);
}
}
m[1][c]=m[2][c];
if(c>=w[1])
m[1][c]=max(m[2][c],m[1][c-w[1]]+v[1]);
}
template <class Type>
void TrackBack(Type **m,int *w,int c,int n,int *x){
for(int i=1;i<=n;i++)
{
if(m[i][c]==m[i+1][c])
x[i]=0;
else
x[i]=1;
}
}
int main()
{
int m[101][101]={0};
int x[101];
int n=5;
int c=10;
int w[5]={2,2,6,5,4};
int v[5]={6,3,5,4,6};
Knapsack(v,w,c,n,m);
return 0;
}
I an writing the algorithm of 01 Knapsack problem.
my Xcode says "No matching function for call to 'Knapsack' "
I am stumbled by the red alarm.
I'm confused for passing arguments.
Is there anyone can help me? Thanks a lot:)
This is not a valid conversion:
int m[101][101]
...
Knapsack(v,w,c,n,m);
// ^-- expects a Type **m
m can decay to type "pointer to array of 101 ints", but no further.
At least type of argument
int m[101][101]={0};
is not equivalent to T ** where T is int.
When this array is passed by value as an argument it is implicitly converted to pointer to its first element and has type int ( * )[101]
Take into account that in any case this function is invalid. For example argument for second parameter w has 5 elements.
int w[5]={2,2,6,5,4};
The valid range of indices for it is [0,4]. n in the function call is equal to 5.
So this statement
int jMax=max(w[n]-1,c);
has undefined behaviour because you are using inadmissible index equal to 5.
template<class Type>
void Knapsack(Type *v,int *w,int c,int n,Type **m)
{
int i,j;
int jMax=max(w[n]-1,c);
//...
You a little bit wrong with definition of functions
template < class Type>
void Knapsack(Type *v,int *w,int c,int n,Type m[][101])
template < class Type>
void TrackBack(Type m[][101],int *w,int c,int n,int *x)