Reputation: 1572
I would like to use function pointers in a specific case. I am using a function foo
with the following prototype
foo(double (*func)(double,double));
I can call foo
the normal way :
double bar(double x, double y) {
//stuff
};
int main(void) {
foo(bar);
return 0;
};
but I would like to freeze the value of x
in order to get a function equivalent to double (*func)(double)
like this :
foo(bar(x,double))
Does a syntax similar to this exists in C++ ?
Upvotes: 2
Views: 1564
Reputation: 5176
Here's two alternatives if you don't wanna use std::bind
/std::function
.
Assuming your compiler supports converting stateless lambdas to function pointers you could use a lambda to bind x
:
void foo(double (*f)(double, double)) { (*f)(3.14159, 2.71828); }
double bar(double x, double y) { return x * y; };
int main()
{
foo([](double x, double y) -> double { return bar(1.0, y); });
return 0;
}
Or you could even change foo
into a template that accepts arbitrary function objects. That way you can use lambdas that have captures:
template<typename TFunc>
void foo(TFunc f) { f(3.14159, 2.71828); }
double bar(double x, double y) { return x * y; };
int main()
{
double fixedprm = 1.0;
foo([fixedprm](double x, double y) -> double { return bar(fixedprm, y); });
return 0;
}
Upvotes: 2
Reputation: 61970
You can use std::bind
if you have C++11. Consider this example that transforms a vector by adding 5 to each element in one swift movement:
#include <iostream>
using std::cout;
#include <functional>
using std::plus;
using std::bind;
using std::placeholders::_1;
#include <vector>
using std::vector;
#include <algorithm>
using std::transform;
int main()
{
vector<int> v {1, 3, 6};
//here we bind the value 5 to the first argument of std::plus<int>()
transform (v.begin(), v.end(), v.begin(), bind (plus<int>(), _1, 5));
for (int i : v)
cout << i << ' '; //outputs "6 8 11"
}
As for your example, I was able to write something close to it like this:
#include <iostream>
using std::cout;
#include <functional>
using std::bind;
using std::function;
using std::placeholders::_1;
void foo (function<double (double, double)> func) //take function object
{
//try to multiply by 3, but will do 2 instead
for (double i = 1.1; i < 5.6; i += 1.1)
cout << func (i, 3) << ' ';
}
double bar (double x, double y)
{
return x * y;
}
int main()
{
foo (bind (bar, _1, 2));
}
Output:
2.2 4.4 6.6 8.8 11
I might have overcomplicated something though. It was actually my first time using both std::bind
and std::function
.
Upvotes: 1