2

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 foothe 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++ ?

2
  • 3
    Check out std::bind. You can bind a value to one or more arguments in a function. Commented May 3, 2012 at 23:03
  • 1
    If you don't have C++11 support for std::function and std::bind with placeholders found in <functional> then you can use the Boost equivalents. Commented May 3, 2012 at 23:17

2 Answers 2

2

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;
}
Sign up to request clarification or add additional context in comments.

Comments

1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.