When you have a function (pointer) as an argument to another function in c++ does the function (that is in the argument) have to be a void function?
eg. Can you have a function like
void run(int (*method)(int, double, vector), int dimension)
here the function method returns an int not a void. I am also having difficulty with the vector. Should it be a &vector?
When I then call it in my main I have it as:
run(jacobi_method(Vnew, V, vec), dimension);
but it does not want to work.
Thanks
run(jacobi_method(Vnew, V, vec), dimension);
should be
run(jacobi_method, dimension);
When you have a function (pointer) as an argument to another function in c++ does the function (that is in the argument) have to be a void function?
No, it can be any type of function; as long as the code using it calls it correctly.
Should it be a &vector?
You mean, should it be a reference? Only you can decide. Is the function supposed to modify it? Then it should be a reference. If not, it's probably more efficient to pass by const reference rather than value.
run(jacobi_method(Vnew, V, vec), dimension);
That's trying to pass the result of calling the function, not a pointer to the function. You want
run(jacobi_method, dimension);
eg. Can you have a function like
void run(int (*method)(int, double, vector), int dimension)
Yes, that is ok, just remember that vector is a template, so it should be
void run(int (*method)(int, double, vector<some_type>), int dimension)
As for your calling,
run(jacobi_method(Vnew, V, vec), dimension);
You can't pass the arguments to the function pointer. You should call it as
run(jacobi_method, dimension);
Here is a complete working code:
#include <vector>
#include <iostream>
using namespace std;
int jacobi_method(int a, double b, vector<int> c)
{
cout << "jacobi_method: " << a << " " << b << endl;
for(int i=0; i<c.size(); i++)
cout << c[i] << endl;
return 8;
}
void run(int (*method)(int, double, vector<int>), int dimension)
{
int result;
vector<int> a;
a.push_back(1337);
a.push_back(1338);
result = method(dimension,2.1,a);
cout << "Result = " << result << endl;
}
int main()
{
run(jacobi_method, 2);
return 0;
}
Yes, it is possible to pass a non void return function as parameter.
A full sample:
#include <iostream>
using namespace std;
int sum(int a, int b) {
return a + b;
}
int substract(int a, int b) {
return a - b;
}
void run(int (*f)(int a, int b), int a, int b) {
int res = f(a, b);
cout << "Result: " << res << endl;
}
int main()
{
run(sum, 10, 5);
run(substract, 10, 5);
return 0;
}
Such definition is legal
void run(int (*method)(int, double, vector), int dimension)
But,
run(jacobi_method(Vnew, V, vec), dimension);
is equivalent to
int r = jacobi_method(Vnew, V, vec);
run(r, dimension);
so you should call:
run(jacobi_method, dimension);
About the vector question, passed by reference (Vector & vec or const Vector & vec for read only) is recommended, because passed by value (Vector vec) actually make a copy, which will lead to low efficient in most conditions.
So just pass vector by value only when you tend to make a copy. The same rule can apply to any other parameter passing, such as other containers and user defined objects
Yes you can have a function that accepts a pointer to another function with a specific signature:
void run(int (*method)(int, double, std::vector<int>), int dimension)
{
std::vector<int> vec;
// put some values in the vector here
int result = method(1, 2.5, vec); // this will call the function
}
And the invocation:
int my_method(int x, double d, std::vector<int> v)
{
int result;
// function code here
return result;
}
run(my_method, dimension);
But, if you want to pass a function with specific parameters to 'run' and also have the ability to change these original parameters inside 'run', then you need to pass in a functor that wraps the method and its arguments, so your 'run' will get the result based on the original parameters, and/or whatever changes 'run' made itself.
Let me know if this is what you really want.
The other posters have pointed out the mistake in your syntax, I'll answer the other question that you have: How do you specify the parameters for the function in question.
If you want to specify them at the moment that you construct the function pointer (as in your original post), your function's type should actually be int (*method)(). You don't expect anyone to be able to change the function parametrs through the pointer, and this is why your pointer is actually to a function accepting no parameters.
If you want to re-use some function that you already have, and assign some parameters, and pass the function as a pointer, with the parameters that you assigned, what you need is std::bind. Some documentation on it: http://en.cppreference.com/w/cpp/utility/functional/bind
In essence, what this allows you to do, is to take one function pointer, pass some parameters to it, and get a new function pointer, which will call your original function, but with the parameters that you specified.
Related
In a program I'm working on, I've declared a vector in main. I have two functions that use the vector: an int function, and a standard void 'print' function. I'm attempting to use a function pointer (pointing to the int function) in the void function, but I get the error that the vector has not been declared, even though it's in main. I've tried declaring the vector outside of main, and the function worked fine, but I'm hesitant on keeping it outside of main. I was wondering if there was some way to use the vector in the void function when it was declared in main. Here's some example code for what I'm asking:
// Example program
#include <iostream>
#include <vector>
using namespace std;
int returnSquare(vector<int>& numbers);
void print(int (*squarePtr)(vector<int>&));
int (*squarePtr)(vector<int>&);
int main()
{
vector<int> v(1);
squarePtr = &returnSquare;
for(int i = 0; i < v.size(); i++)
{
v.at(i) = i * 25;
cout << v.at(i) << " ";
}
print(squarePtr);
return 0;
}
int returnSquare(vector<int>& numbers)
{
int product = 0;
for(int i = 0; i < numbers.size(); i++)
{
product = numbers.at(i) * numbers.at(i);
}
return product;
}
void print(int (*squarePtr)(vector<int>&))
{
int answer = (*squarePtr)(v);
cout << answer << endl;
}
In your function print you have just one parameter. To call your squaring function you need to pass the vector to square to it, something like:
void print(int (*squarePtr)(vector<int>&), vector<int> &v)
{
int answer = (*squarePtr)(v);
cout << answer << endl;
}
Without that the variable v is not visible inside the function. The call should look like:
print(squarePtr, v);
Less important. You use the squarePtr name in your global definitions twice. This does not bring clarity to your code. You better write:
void print(int (*workerFuncPtr)(vector<int>&));
int (*squarePtr)(vector<int>&);
void print (int (*squarePtr)(vector<int>&))
This parameter only accepts a pointer to your square function, that's it. It doesn't hold a pointer or a reference to your v variable. Your print function has no idea what v is, unless you pass v as an argument, or make v a global variable (which is what you did moving it out of main).
Do this:
// Modify your print definition to accept a reference to your vector `v`
void print(int (*squarePtr)(vector<int>&), vector<int>& v);
// Add `v` as the second argument to your print call
print(squarePtr, v);
// Modify the definition of your print function to accept a reference to your vector `v`
void print(int (*squarePtr)(vector<int>&), vector<int>& v)
{
...
}
I am completely new to structs and user defined datatypes, and i was trying to create a function that returns a struct:
The problem is highlight by the comment:
#include <iostream>
using namespace std;
struct num {
int n[2];
};
num func( num x, int a, int b) {
x.n[0] = a+b;
x.n[1] = a*b;
return x;
}
int main() {
int x,y;
num s1;
cout << "enter: ";
cin >> x >> y;
func(s1,x,y);
cout << s1.n[0] << "\n" << s1.n[1]; // THIS GIVES ERROR
cout << func(s1,x,y).n[0] << "\n" << func(s1,x,y).n[1]; // THIS DOENST GIVE ERROR
return 0;
}
I understand that second method makes sense and returns the struct variable. then putting a dot addresses the inner variable of struct.
But i dont understand why first method fails, or gives odd output. The function has done its job, ie made s1.n[0] = x + y and s1.n[1] = x*y
Now, printing s1.n[0] should print x + y only. How can we check and correct the internal workings of the function?
You have to assign the returned value to the structure object in main
s1 = func(s1,x,y);
Inside the body the function deals with a copy of the original object. It does not change the original object because it is passed by value.
Another approach is to pass the structure by reference
void func( num &x, int a, int b) {
x.n[0] = a+b;
x.n[1] = a*b;
}
In this case in main you could just write
func(s1,x,y);
Or you could use even so-called C approach of passing by reference
void func( num *x, int a, int b) {
x->n[0] = a+b;
x->n[1] = a*b;
}
and call it like
func( &s1, x, y );
As for this statement
cout << func(s1,x,y).n[0] << "\n" << func(s1,x,y).n[1];
then you access data members of two temporary objects returned by the two calls of the function. After executing this statement these temporary objects will be deleted.
It looks like you are never assigning the return value of func(). Your function returns the struct, but you are never assigning it. To fix this, you should be able to simply say: s1 = func(s1,x,y); This will assign the modified version of the struct to the s1 variable.
Alternatively, you could rewrite func() to accept a pointer to the struct. This would allow you to modify the struct without having to return it:
void func( num *x, int a, int b) {
x->n[0] = a+b;
x->n[1] = a*b;
}
Then you would just change your call to func() to say: func(&s1, x, y);
You are not passing your struct by reference, hence the result. Try the following:
void func(num &x, int a, int b) {
x.n[0] = a+b;
x.n[1] = a*b;
}
There's no need for the function to return anything since your struct is passed by reference and it will be changed anyway. Void would fit better.
This is because you have passed the struct by value while your intentions look like you want to pass by reference.
Check this link : http://courses.washington.edu/css342/zander/css332/passby.html
num func( num &x, int a, int b)
should fix your problem
I want to make function which has function pointer as a parameter.
#include <iostream>
using namespace std;
class test{
public:
test(){};
double tt(double input){
return input;
};
};
double fptr_test(double (*fptr)(double), double input){
return fptr(input);
}
int main(){
test t;
cout << t.tt(3) << endl;
cout << fptr_test(t.tt, 3) << endl; // This line doesn't work
cout << fptr_test(&test::tt, 3) << endl; // This line can't compile
return 1;
}
But it doesn't work.
How could I pass class member function as a parameter?
Can I call the member function without instantiation?
If you want to pass a pointer to a member-function, you need to use a member-function-pointer, not a pointer for generic free functions and an object to invoke it on.
Neither is optional.
double fptr_test(test& t, double (test::*fptr)(double), double input){
return t.*fptr(input);
}
// call like this:
fptr_test(&test::tt, 3); // Your second try
A function pointer and a member function pointer have incompatible types. For example, the type of &test::tt is
double (test::*)(double)
rather than
double (*)(double)
The reason for this difference is that a [non-static] member function has a hidden parameter: the pointer to the object the member function is applied, too, i.e., this. The way to a normal function pointer out of a member function is to delegate via a function which supplies the this pointer and, thus, takes an extra argument.
In C++ it is much more useful to not take function pointers as arguments to functions which can be customized by a function but rather to take a function object. This approach comes in two flavors:
The fast approach is to make the function object type a template argument and to just pass whatever function object you got directly. For example, you fptr_test() would look like this:
template <typename Fun>
double fptr_test(Fun fun, double input) {
return fun(input);
}
The implicit concept used is a function callable with a double argument which yields are result convertible to double.
Especially when the functions being called need to be compiled separately, using a template for each kind of function object isn't viable. In that case it is much more reasonable to use a type-erased representation, i.e., std::function<...>, e.g.:
double fptr_test(std::function<double(double)> fun, double input) {
return fun(input);
}
In both cases the function object takes just one argument while your member function takes two: the object to call the function on and the double argument. You'd std::bind(...) the first argument to an object and pass the resulting object to fptr_test():
test object;
std::cout << fptr_test(std:bind(&test::tt, &object, std::placeholders::_1), 3) << '\n';
std::cout << fptr_test([&](double input){ return object.tt(input); }, 3) << '\n';
The code uses two separate approaches to bind the object: the first uses std::bind() while the second uses a lambda function. Both of these calls should work with both of the implementation of fptr_test() provided.
What you probably want is this:
#include <iostream>
#include <functional>
using namespace std;
class test{
public:
test(){};
double tt(double input){
return input;
};
};
double fptr_test( std::function<double(double)> func, double input){
return func(input);
}
int main(){
using namespace std::placeholders;
test t;
cout << t.tt(3) << endl;
cout << fptr_test( std::bind( &test::tt, t, _1 ), 3) << endl;
return 0;
}
Btw - when your program finishes correctly you suppose to return 0 from main()
Here is a code after modification.
#include <iostream>
using namespace std;
class test{
public:
test(){};
double tt(double input){
return input;
};
};
double fptr_test(test* t, double (test::*fptr)(double), double input){
return (t->*fptr)(input);
}
int main(){
test t;
cout << t.tt(3) << endl;
cout << fptr_test(&t, &test::tt, 3) << endl;
return 1;
}
so in my main function, I have a called function with arguments stored in a variable. I run my program, and the variable containing the function is executed. I thought that when I store functions or anything in a variable, then it shouldn't execute until I tell it to.
for example:
int cycle1 = cycleList(argument1, argument2);
this statement above is now executed on my screen. Is this a correct way to write code? I wanted to store the function in a variable, and later use the variable somewhere in my code.
If you want to store a function, you need to make a pointer to the function, not call the function, which is what you're doing. Try this instead:
#include <functional>
std::function<int (int, int)> cycle1 = cycleList;
Or, if you don't have access to C++11, try this:
int (*cycle1)(int, int) = cycleList;
Then later you can call:
cycle1(argument1, argument2);
If you wanted to store the result of the function at that point in time in the program's runtime, then yes, you are doing it correctly.
Functions can accept parameters and can return a result. Where the functions are declared in your program does not matter, as long as a functions name is known to the compiler before it is called.
Let’s take a look at an example;
int Add(int num1, int num2)
{
return num1 + num2;
}
int main()
{
int result, input1, input2;
cout << "Give a integer number:";
cin >> input1;
cout << "Give another integer number:";
cin >> input2;
result = Add(input1,input2);
cout << input1 << " + " << input2 << " = " << answer;
return 0;
}
Here I defined Add() function before main() so main knows that Add() is defined. So in main() when add() calls it sends two parameter and get results with return num1+ num2 . Then it sends returned value to result.
As far as what I can get from your query is that you are calling a parameterized method in your class which is returning some value. You want to store the result of that method in a variable so that you can use it as per your need. But, you want to eliminate the overhead of computing that method even when you don't need it. It should be executed only when you require it or on the basis of a particular condition.
What I can suggest you in this case is, have this code in a condition. There must be an appropriate time or a satisfied condition when you want that method to execute and compute the result for you.
For instance:
public class BaseCondition {
public int compute(int a, int b) {
return (a + b);
}
public boolean set(boolean flag) {
flag = true;
return flag;
}
public int subtract(int a, int b) {
return (a - b);
}
public int callCompute(int a, int b) {
boolean flag = false;
int computedVal = 0;
if (a < b || a == b) {
flag = set(flag);
}
if (flag) {
computedVal = compute(a, b);
} else {
computedVal = subtract(a, b);
}
return computedVal;
}
public static void main(String[] args) {
BaseCondition obj = new BaseCondition();
int a = 11;
int b = 51;
System.out.println("Result=" + obj.callCompute(a, b));
}
}
Here, you can find compute will be called only on the basis of flag which is being set only when a condition is satisfied.
Hope it helps :)
You can also do the following using auto's
#include <iostream>
using namespace std;
int Foo()
{
return 0;
}
int main()
{
// your code goes here
auto bar = Foo;
return 0;
}
In C++, variables store values, not functions; and an expression that calls a function to get a value does so immediately. So your example calls the function to get an int value, then stores that value in the variable.
There are ways to do what you want:
// Store a lambda function object, capturing arguments to call it with.
// This doesn't call the function.
auto cycle1 = [=]{cycleList(argument1, argument2);};
// Call the function later. This calles 'cycleList' with the captured arguments.
int result = cycle1();
but you should probably learn the basics before doing this sort of thing.
Functions return results, and function objects can be stored (and copied around) themselves, including their arguments:
#include <iostream>
int cycleList(int arg1, int arg2) { return arg1 + arg2; }
struct cycleListObj
{
int arg1, arg2;
// constructor stores arguments for later use
cycleListObj(int a1, int a2): arg1(a1), arg2(a2) {}
// overload function call operator()
int operator()() { return arg1 + arg2; }
};
int main()
{
int result1 = cycleList(1, 1); // stores 2 into result1
cycleListObj fun(1, 1); // defines a function object fun with arguments 1, 1
int result2 = fun(); // calls the function object, and stores the result into result2
std::cout << result1 << result2; // outputs 22
}
Live Example
As others have shown, the C++ Standard Library defines its own generic function object std::function, but for many purposes you can define them yourself as well.
You can also store function pointer, but then you still have to supply the arguments at the call site. With a function object, you can store the arguments first, and call it later.
I made a program that calls this function. I know this because "Int Strength has been called" appears in the output box. However, it will not change the values that I tell it to do.
I want it to get integer values from main(), then use them and return the new values.
I am using a header file that only contains "int strength(int a, int s, int i)"
int strength(int a, int s, int i)
{
using namespace std;
cout << "Int Strength has been called" << endl;
a = a + i;
s = s - i;
return a;
return s;
}
Multiple errors. Firstly, if you want the arguments to be modified (more precisely, the modification being effective out of the scope of the function), you have to pass the values by reference:
int strength(int &a, int &s, int &i)
Second, you seem to be concerned about return a; return s; returning two values. It doesn't - the very first return encountered exits the function immediately.
The values only change within the function. Variables are passed by value not reference.
Use references as the parameters.
int strength(int& a, int& s, int& i)
You're passing by value. You need to pass a pointer to the memory allocated in the caller that contains the data you wish to modify.
void strength(int *a, int *s, int i)
{
using namespace std;
cout << "Int Strength has been called" << endl;
*a += i;
*s -= i;
}
Then call it thusly:
a = 1;
s = 2;
i = 3;
strength(&a, &s, i);