Function pointer from a class function

I was trying to find a good way to associate curves/paths with objects, and I ran into function pointers which seem to be exactly what I want.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <cmath>
Coordinate unit_circle(double t) // coordinate is a simple (x, y) point with proper overloads
{
    return Coordinate(std::cos(t),
                      std::sin(t));
}

#include <iostream>
int main()
{
    using namespace std;
    const double Pi = 3.14159265358979323;
    Movable object; // Movable class has a function pointer declared Coordinate(*mpPath)(double);
    object.setPath(unit_circle);
    cout << object.position(Pi / 2) << endl;
}

The above is working just fine and seems to be an elegant way for the user to set my object's path for later use.

What I'm trying to now is associate my object with the path of a Line, but I have Line as another class, not just a function.
Ex: I want the result to be the following
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Line {
  public:
    Line(const Coordinate& start, const Coordinate& end)
    : mP1(start), mP2(end)
    {}

    //this is the position function I would want to have associated:
    Coordinate path(double t)
    {
        return (1-t)*mP1 + t*mP2;
    }
  private:
    Coordinate mP1;
    Coordinate mP2;
};

int main()
{
   Line my_line(Coordinate(0.0, 0.0),
                Coordinate(10.0, 10.0));
   Movable object2;
   object2.setPath(my_line);
   cout << object2.position(0.5); // prints (5, 5)
}


Can anyone point me in the right direction on how to make "my_line" return a function pointer to my class's path function? Is this even possible? Is this a good way to use function pointers in general?

Thank you for reading, hopefully I put enough code to explain myself, was trying to avoid posting a wall of text.
Last edited on
Something like:
1
2
3
4
5
6
7
8
9
10
11
12
13
//In Line
std::function<Coordinate(double)> get_path() const
{
    return [this](double t){ return (1-t)*this->mP1 + t*this->mP2;};
}

//In Movable
std::function<Coordinate(double)>  mpPath;
template<typename T>
void setPath(const T& obj)
{
    mpPath = obj.get_path();
}
http://ideone.com/3HKAsd
Last edited on
That example is so helpful! Take all my gratitude.
Am I correct in saying that line 4 is a "lambda" function? (I haven't used those before but seems like an interesting subject to learn.)
So your get_path() function (creates and?) returns a function pointer (std::function) to a self-contained function?

Also
1
2
3
4
5
 template<typename T>
void setPath(const T& obj)
{
mpPath = obj.get_path();
}
helps a lot too, I thought I'd have to do some weird overload to make it work, but this is great.
Last edited on
Am I correct in saying that line 4 is a "lambda" function?
Yes
So your get_path() function (creates and?) returns a function pointer (std::function) to a self-contained function?
std::function is a function object: a class which overloads operator() so it can be called as simple function and additionally can store additional information inside. Capturing lambdas (those with something written inside square brackets) cannot be converted to function pointer, so you have to store them in those function classes. (if you want to return them. If you just need to use them locally it is better to use auto and store them in their native type)
Last edited on
One last thing if you don't mind:
How costly is calling the position function now in comparison to what I was doing before with function pointers?
1
2
3
4
5
6
7
8
9
// what I was doing before which worked with the circle function
Coordinate Movable::position(double t)
{
    return mpPath(t);
}
void Movable::setPath(Coordinate(*pPath)(double))
{
    mpPath = pPath;
}

In working code, I imagine that my setPath() function would only be called a limited number of times to set things up, but my position() function would be called many times at small increments of t. Is there a lot of overhead in using the lambda with a function object? I ask out of ignorance. I guess I could do some time tests to compare calling the position of the path as a circle parametrization vs the Line parametrization.
Edit: I did some really basic time tests to compare use of circle function in both my code and yours, and it seems that the function pointer code runs faster than the code with the std::function and lambda, is this what I should expect?

_______________________________

Edit side note:
Also I figured out a good way to make it so your code works with both pure functions and class member stuff
1
2
3
4
5
6
7
8
9
10
    template<typename T>
    void setPath(const T& obj)
    {
        mpPath = obj.get_path();
    }

    void setPath(Coordinate(*pPath)(double))
    {
        mpPath = pPath;
    }

Yay for function overloading, now I can do this.
1
2
3
4
5
6
7
8
9
Coordinate circle(double t)
{
    return Coordinate(std::cos(t),
                      std::sin(t));
}
    //...main
    object2.setPath(my_line);
    object2.setPath(circle);
    std::cout << object2.position(0.5)
Last edited on
is this what I should expect?
Yes. Capturing lambda should take current context, save it and then pass full-fledged object with additional data around.
Binding an object to function and pass information about binded object cost something.

std::function uses some kind of type erasure to store any callable object, so it incurs some overhead too.
Being able to store any callable object with specific signature cost something too.
Alright, makes sense. Once I did more tests it seems the difference actually isn't that much (some other posts I googled had talks of a magnitude of difference, but I can't get something like that to happen, which is a good thing :).
Topic archived. No new replies allowed.