Call class method non-static initialised by pointer - c++

I'm trying call a method initialised by pointer to a method of other class, i've followed this:
but it has not worked for me.
consider this:
class y
{
public:
int GetValue(int z)
{
return 4 * z;
}
};
class hooky
{
public:
int(hooky::*HookGetValue)(int);
};
int(hooky::*HookGetValue)(int) = (int(hooky::*)(int))0x0; // memory address or &y::GetValue;
int main()
{
hooky h; // instance
cout << h.*HookGetValue(4) << endl; // error
return 0;
}
the error that produces is:
[Error] must use '.' or '->' to call pointer-to-member function in
'HookGetValue (...)', e.g. '(... ->* HookGetValue) (...)'

The correct syntax to invoke a member function pointer is
(h.*HookGetValue)(4)
Update: the reason original code does not work as expected is because of operator precedence of C++: function invocation () is having higher precedence than ptr to member .*. Which means
h.*HookGetValue(4)
will be see as
h.*(HookGetValue(4))

Related

How to call function pointer for class member function

I tried to implement a function pointer calling to the class member. I have implemented the sample and assigned the function pointer successfully. But if I try to call the function pointer it is throwing an error. Kindly refer below sample code of what I implemented and assist me on this.
#include <iostream>
using namespace std;
class myfunpoin
{
public:
int addd(int a,int b)
{
return a + b;
}
int sub(int a, int b)
{
return a - b;
}
};
int main()
{
myfunpoin a;
int (myfunpoin::*myval)(int, int);
myval =&myfunpoin::addd;
myval(1, 2);//i want to invoke this function pointer but getting error
getchar();
return 0;
}
myval(1, 2);
This cannot work because you haven't passed the implicit instance argument.
A pointer to member function is called like a member function, except in place of the function name, you have indirection operator and the pointer to member function. Example:
(a.*myval)(1, 2);
The parenthesis are needed because function call operator has higher precedence and the expression would have a wrong meaning otherwise.

compile error about template deduction on c++

#include <iostream>
template <int N>
class X {
public:
using I = int;
void f(I i) {
std::cout << "i: " << i << std::endl;
}
};
template <int N>
void fppm(void (X<N>::*p)(typename X<N>::I)) {
p(0);
}
int main() {
fppm(&X<33>::f);
return 0;
}
I just don't understand the compile error message of the code.
error: called object type 'void (X<33>::*)(typename X<33>::I)' is not a function or function pointer
p(0);
I think p is a function which returns void and takes int as its argument. But apparently, it's not. Could somebody give me clue?
Since p is a pointer to a nonstatic member function, you need an instance to call it with. Thus, first instantiate an object of X<33> in main:
int main() {
X<33> x;
fppm(x, &X<33>::f); // <-- Signature changed below to accept an instance
Then in your function, change the code to accept an instance of X<N> and call the member function for it:
template <int N>
void fppm(X<N> instance, void (X<N>::*p)(typename X<N>::I)) {
(instance.*p)(0);
}
The syntax may look ugly but the low precedence of the pointer to member operator requires the need for the parentheses.
As denoted in the comments already, p is a pointer to member function, but you call it like a static function (p(0);). You need a concrete object to call p on:
X<N> x;
(x.*p)(0);
// or:
X<N>* xx = new X<N>();
(xx->*p)(0);
delete xx;
Be aware that the .*/->* operators have lower precedence than the function call operator, thus you need the parentheses.
Side note: Above is for better illustration, modern C++ might use auto keyword and smart pointers instead, which could look like this:
auto x = std::make_unique<X<N>>();
(x.get()->*p)(0);

called object type 'void (B::*)(int)' is not a function or function pointer

I am trying to wrap my head around passing method as function argument. Here is a simplified example which returns a compilation error that I don't understand
class B
{
private:
int j;
public:
void foo(int i){std::cout << i + this->j << std::endl;}
void setj(int J){j=J;}
};
class A
{
private:
B b;
public:
void call(void (B::*fun)(int i), int i) { b.*fun(i); }
void setBj(int j){b.setj(j);}
};
int main()
{
A a;
a.setBj(40);
a.call(B::foo, 2);
}
When compiled with
g++ -std=c++11 b.cpp -o b
I get
b.cpp:22:50: error: called object type 'void (B::*)(int)' is not a function or
function pointer
void call(void (B::*fun)(int i), int i) { b.*fun(i); }
~~~^
b.cpp:31:12: error: call to non-static member function without an object
argument
a.call(B::foo, 2);
~~~^~~
2 errors generated.
I don't understand the first error message. I understand that I am calling foo as if it was a static method, which it is not but I don't understand how to pass a non-static method.
Two problems.
To invoke a pointer to a member function, you need to first apply a pointer to member access operator, that obtains a callable expression. Then you add a call. Now it just so happens that .* is of lower precedence than the function call operator. So the first fix:
(b.*fun)(i)
A a pointer to member function can only be obtained by applying unary & on the fully qualified function name. So the second fix:
a.call(&B::foo, 2);

C++ Function call via an object with public member pointer to function, without using dereference operator

Alright, I think the title is sufficiently descriptive (yet confusing, sorry).
I'm reading this library: Timer1.
In the header file there is a public member pointer to a function as follows:
class TimerOne
{
public:
void (*isrCallback)(); // C-style ptr to `void(void)` function
};
There exists an instantiated object of the TimerOne class, called "Timer1".
Timer1 calls the function as follows:
Timer1.isrCallback();
How is this correct? I am familiar with calling functions via function pointers by using the dereference operator.
Ex:
(*myFunc)();
So I would have expected the above call via the object to be something more like:
(*Timer1.isrCallback)();
So, what are the acceptable options for calling functions via function pointers, as both stand-alone function pointers and members of an object?
See also:
[very useful!] Typedef function pointer?
Summary of the answer:
These are all valid and fine ways to call a function pointer:
myFuncPtr();
(*myFuncPtr)();
(**myFuncPtr)();
(***myFuncPtr)();
// etc.
(**********************************f)(); // also valid
Things you can do with a function pointer.
1: The first is calling the function via explicit dereference:
int myfunc(int n)
{
}
int (*myfptr)(int) = myfunc;
(*myfptr)(nValue); // call function myfunc(nValue) through myfptr.
2: The second way is via implicit dereference:
int myfunc(int n)
{
}
int (*myfptr)(int) = myfunc;
myfptr(nValue); // call function myfunc(nValue) through myfptr.
As you can see, the implicit dereference method looks just like a normal function call -- which is what you’d expect, since function are simply implicitly convertible to function pointers!!
In your code:
void foo()
{
cout << "hi" << endl;
}
class TimerOne
{
public:
void(*isrCallback)();
};
int main()
{
TimerOne Timer1;
Timer1.isrCallback = &foo; //Assigning the address
//Timer1.isrCallback = foo; //We could use this statement as well, it simply proves function are simply implicitly convertible to function pointers. Just like arrays decay to pointer.
Timer1.isrCallback(); //Implicit dereference
(*Timer1.isrCallback)(); //Explicit dereference
return 0;
}
You don't have to dereference a function pointer to call it. According to the standard ([expr.call]/1),
The postfix expression shall have
function type or pointer to function type.
So (*myFunc)() is valid, and so is myFunc(). In fact, (**myFunc)() is valid too, and you can dereference as many times as you want (can you figure out why?)
You asked:
Timer1 calls the function as follows:
Timer1.isrCallback();
How is this correct?
The type of Timer1.isrCallback is void (*)(). It is a pointer to a function. That's why you can use that syntax.
It is similar to using:
void foo()
{
}
void test_foo()
{
void (*fptr)() = foo;
fptr();
}
You can also use:
void test_foo()
{
void (*fptr)() = foo;
(*fptr)();
}
but the first form is equally valid.
Update, in response to comment by OP
Given the posted definition of the class you would use:
(*Timer1.isrCallback)();
To use
(Timer1.*isrCallback)();
isrCallback has to be defined as a non-member variable of whose type is a pointer to a member variable of TimerOne.
void (TimerOne::*isrCallback)();
Example:
#include <iostream>
class TimerOne
{
public:
void foo()
{
std::cout << "In TimerOne::foo();\n";
}
};
int main()
{
TimerOne Timer1;
void (TimerOne::*isrCallback)() = &TimerOne::foo;
(Timer1.*isrCallback)();
}
Output:
In TimerOne::foo();
(Test this code)
If you want to define isrCallbak as a member variable of TimerOne, you'll need to use:
#include <iostream>
class TimerOne
{
public:
void (TimerOne::*isrCallback)();
void foo()
{
std::cout << "In TimerOne::foo();\n";
}
};
int main()
{
TimerOne Timer1;
Timer1.isrCallback = &TimerOne::foo;
// A little complicated syntax.
(Timer1.*(Timer1.isrCallback))();
}
Output:
In TimerOne::foo();
(Test this code)

How do you pass a function of a class as a parameter to another function of the same class

i basically want to use a dif function to extract a different element of a class (ac).
the code is similar to this:
.h:
class MyClass
{
public:
double f1(AnotherClass &);
void MyClass::f0(AnotherClass & ac, double(MyClass::*f1)(AnotherClass &));
};
.cc:
double MyClass::f1(AnotherClass & ac)
{
return ac.value;
}
void MyClass::f0(AnotherClass & ac, double(MyClass::*f1)(AnotherClass &))
{
std::cout << f1(ac);
}
didn't work, it gives error#547 "nonstandard form for taking the address of a member function"
EDIT:
I call it from:
void MyClass(AnotherClass & ac)
{
return f0(ac,&f1); // original and incorrect
return f0(ac,&Myclass::f1); //solved the problem
}
However, I have another error:
std::cout << f1(ac);
^ error: expression must have (pointer-to-) function type
Look at where the error points. I bet it's not on the function declaration line, but on how you call it.
Observe:
struct foo
{
void bar(void (foo::*func)(void));
void baz(void)
{
bar(&foo::baz); // note how the address is taken
bar(&baz); // this is wrong
}
};
You're getting your error because you're calling the function incorrectly. Given my foo above, we know this won't work:
baz(); // where did the foo:: go?
Because baz requires an instance to be called on. You need to give it one (I'll assume this):
std::cout << (this->*f1)(ac);
The syntax is a bit weird, but this operator ->* says: "take the member function pointer on the right, and call it with the instance on the left." (There is also a .* operator.)
You still haven't posted the code where you create the pointer to member which is what the error seems to be about, but there is an issue with how you use it.
To use a pointer to member you need to use one of ->* or .* operators with a pointer or reference to an appropriate instance of the class. E.g.:
void MyClass::f0(AnotherClass & ac, double(MyClass::*f1)(AnotherClass &))
{
std::cout << (this->*f1)(ac);
}
You can call the function like so:
void f()
{
AnotherClass ac;
MyClass test;
test.f0( ac, &MyClass::f1 );
}
Note that for pointers to members you need &, unlike normal function names which convert implicitly to function pointers.