Is it possible to somehow declare and assign a function to function pointer func in main() without having an actual function add()?
Current Code:
#include <iostream>
int add(int a, int b)
{
return a + b;
}
int main()
{
typedef int (*funcPtr)(int a, int b);
funcPtr func = &add;
std::cout << func(2,3) << std::endl;
}
Preferred Style: (if possible)
#include <iostream>
int main()
{
typedef int (*funcPtr)(int a, int b);
funcPtr func = (funcPtr){return a + b}; // is something like this possible?
std::cout << func(2,3) << std::endl;
}
Is there a way to assign a function to function pointer dynamically like my last code?
You can use lambda; which could convert to function pointer implicitly if capture nothing.
funcPtr func = [](int a, int b) {return a + b;};
LIVE
Related
It is well known that you cannot create a reference to a member function in C++ [source].
For those that don't know. The issue come when you want to do something similar to
class A
{
public:
void Add(int a, int b)
{
std::cout << "Sum is " << a + b << std::endl;
}
void CallAdd(int a, int b, void (*func)(int, int))
{
func(a, b);
}
};
and then call Add through CallAdd:
A a;
a.Add(3, 7); // This works fine
a.CallAdd(3, 7, &a.CallAdd); //This does not compile
The error is
error: cannot create a non-constant pointer to member function
a.CallAdd(3, 7, &a.CallAdd);
Which would not occur if it wiere outside a class.
There is a work around using std::function/lambda. Like this:
class A
{
public:
function<void(int, int)> AddFunc = [](int a, int b)
{
std::cout << "Sum is " << a + b << std::endl;
};
void CallAdd(int a, int b, std::function<void(int, int)> &func)
{
func(a, b);
};
};
int main()
{
A a;
a.CallAdd(3, 7, a.AddFunc);
}
This works fine but the problem is that computation time increases a lot (obviously this is just a minimal reproducible example) compared to simply calling the function.
Is there a way to increase computation speed or is this the best one can do?
For context, I have an algorithm to integrate functions, and I want to change integrands at will so the integrand must be a function parameter.
Pass the function object (or lambda) to a templated member function as follows:
#include <concepts>
#include <iostream>
inline auto myAddFunc = [](int a, int b) {
std::cout << "Sum is " << a + b << std::endl;
};
class A
{
public:
template <std::regular_invocable<int,int> Func>
void CallFunc(int a, int b, Func func)
{
func(a, b);
};
};
int main()
{
A a;
auto mySubFunc = [](int a, int b) {
std::cout << "Difference is " << a - b << std::endl;
};
a.CallFunc(3, 7, myAddFunc);
a.CallFunc(7, 3, mySubFunc);
}
If I have a friend function can I somehow use set() to assign a value to a private variable inside the function? Or some other method?
Example : Here I have 3 private variables. I tried to make the sum of 2 of them and store the result in the 3rd one. I tried to do it with a setter but the result is 0. In main it works, but I don't know if I can make it work in the class function.
#include <iostream>
using namespace std;
class Function{
private:
int a;
int b;
int sum;
public:
Function() = default;
Function(int _a, int _b);
friend int sumNumber(Function f);
//Setter and getter
int getA() const;
void setA(int a);
int getB() const;
void setB(int b);
int getSum() const;
void setSum(int sum);
};
Function::Function(int _a, int _b) {
this->a = _a;
this->b = _b;
}
int Function::getA() const {
return a;
}
void Function::setA(int a) {
Function::a = a;
}
int Function::getB() const {
return b;
}
void Function::setB(int b) {
Function::b = b;
}
int Function::getSum() const {
return sum;
}
void Function::setSum(int sum) {
Function::sum = sum;
}
int sumNumber(Function f) {
int a = f.getA();
int b = f.getB();
int sum = a + b;
f.setSum(sum);
return sum;
};
int main() {
Function AA(1,2);
cout << sumNumber(AA);
cout << " " << AA.getSum();
AA.setSum(sumNumber(AA));
cout << "\n" << AA.getSum();
return 0;
}
Output :
3 0
3
As alluded to in the comments, the issue is with this function:
int sumNumber(Function f) {
int a = f.getA();
int b = f.getB();
int sum = a + b;
f.setSum(sum);
return sum;
};
Let us walk through your code:
Function AA(1,2);
You create a object of type Function, called AA and you allocate each member variable of that object via the constructor (1 and 2).
cout << sumNumber(AA);
You call your method (sumNumber) and pass to it a copy of your variable AA. That function adds the two numbers together and internally calls setSum.
cout << " " << AA.getSum();
You now try to display the sum value by calling the getSum method. But the issue was that you passed a copy of your variable into the sumNumber function. The original AA variable was left alone.
To fix this you need to adjust your function by adding an ampersand &. Like this:
int sumNumber(Function& f) {
int a = f.getA();
int b = f.getB();
int sum = a + b;
f.setSum(sum);
return sum;
};
Now your variable AA is being passed by reference and not by value. There are lots of tutorials about this concept.
How do I properly pass member function as a parameter?
MyCode:
#include <iostream>
using namespace std;
class Test
{
public:
int add(int a, int b)
{
return a + b;
}
int sub(int a, int b)
{
return a - b;
}
typedef int (*funcPtr)(int a, int b);
int myFunc(funcPtr func, int a, int b)
{
return func(a, b);
}
void setup()
{
cout << myFunc(&Test::add, 5, 3) << endl;
cout << myFunc(&Test::sub, 5, 3) << endl;
}
};
int main()
{
Test test;
test.setup();
}
Result:
Error: Cannot initialize a parameter of type 'Test::funcPtr' (aka 'int
()(int, int)') with an rvalue of type 'int (Test::)(int, int)'
Expected Result:
8
2
Your methods should be "regular" functions. add static to them to allow to use them with function pointers:
class Test
{
public:
static int add(int a, int b)
{
return a + b;
}
static int sub(int a, int b)
{
return a - b;
}
// ...
};
If you really pointer on method, you should replace int (*funcPtr)(int a, int b) by int (Test::*funcPtr)(int a, int b) and use something like that instead:
class Test
{
public:
int add(int a, int b)
{
return a + b;
}
int sub(int a, int b)
{
return a - b;
}
typedef int (Test::*funcPtr)(int a, int b);
int myFunc(funcPtr func, int a, int b)
{
return (this->*func)(a, b);
}
void setup()
{
cout << myFunc(&Test::add, 5, 3) << endl;
cout << myFunc(&Test::sub, 5, 3) << endl;
}
};
You should read about std:: function and std::bind. The first thing will allow you to store a function pointer with multiple form (Functor, lamda, binded), and the second will allow you to bind parameters to your function call (In your case, you want to bind the instance of the class that is needed to call your function).
std:: function<int(int, int)> func = std::bind(&Class::Method, instancePtr, std::placeholders::_1, std:: placeholders::_2);
int result = func(a, b);
However, in your context, your methods should be marked as static (They are not using any non-static member of your class), but the example and the explanation I provided answer to your base question
Firstly, based on your question the best solution here will be without using the pointer instead declare your methods as static and call them directly as given below.
That solution will generate the right results without using the complexity of pointers.
Simple is better if you do not need to use pointers it is better to not use them. code will be more readable as well.
Following code works i tested it:
#include <iostream>
using namespace std;
class Test
{
public:
static int add(int a, int b)
{
return a + b;
}
static int sub(int a, int b)
{
return a - b;
}
void setup()
{
cout << add( 5, 3) << endl;
cout << sub(5, 3) << endl;
}
};
int main()
{
Test test;
test.setup();
}
I have this example code of using pointer to member function, which I want to change during runtime, but I cannot make it work. I've already tried this->*_currentPtr(4,5) (*this)._currentPtr(4, 5). What is the proper way of calling pointer to method inside same class ?
The error : expression must have (pointer-to-) function type
#include <iostream>
#include <cstdlib>
class A {
public:
void setPtr(int v);
void useFoo();
private:
typedef int (A::*fooPtr)(int a, int b);
fooPtr _currentPtr;
int foo1(int a, int b);
int foo2(int a, int b);
};
void A::setPtr(int v){
if(v == 1){
_currentPtr = foo1;
} else {
_currentPtr = foo2;
}
}
void A::useFoo(){
//std::cout << this->*_currentPtr(4,5); // ERROR
}
int A::foo1(int a, int b){
return a - b;
}
int A::foo2(int a, int b){
return a + b;
}
int main(){
A obj;
obj.setPtr(1);
obj.useFoo();
return 0;
}
You need to tell the compiler which class the foos are coming from (otherwise it thinks they're functions from global scope):
void A::setPtr(int v){
if(v == 1){
_currentPtr = &A::foo1;
// ^^^^
} else {
_currentPtr = &A::foo2;
// ^^^^
}
}
and you need a set of parentheses here:
std::cout << (this->*_currentPtr)(4,5);
// ^ ^
Is it possible to create a function which takes a pointer to another function? How does the prototype of such a function look like?
typedef int (*func)(float, char);
int something_that_takes_a_func(func f) { return f(3.14, 3); }
int foo(float a, char b) { return a - b; }
std::cout << something_that_takes_a_func(&foo) << "\n";
void f(int(*Func)())
{
int a = Func();
}
and for a member function:
void f(int(cLass::*Func)())
{
cLass *c = new cLass;
int a = (c->*Func)();
}