Programming Forums

Programming Forums (http://www.programmingforums.org/forumindex.php)
-   C++ (http://www.programmingforums.org/forum15.html)
-   -   Pointers to functions question (http://www.programmingforums.org/showthread.php?t=14025)

Soulstorm Sep 23rd, 2007 4:41 AM

Pointers to functions question
 
Is there any way I can create a pointer to an arbitrary function (whose arguments need not be specified?

Purpose:
OpenGL. I have a class in which want to be able to define the material properies, and then associate the void pointer of that class to a function that draws the object. But I want to be able to use any function available, like glutDrawTorus or a custom function made by me.

:

class test{
class test {
public:
        float *materialProperty1;
        float *materialProperty2;
        float *materialProperty3;
       
        void (*functionToCall)();
       
        void setFunction( void (*func)() )
        {
                functionToCall = func;
        }
};


That is the general idea, but that won't work if the function I am associating to funcToCall has any number of arguments.

Is there any way I can bypass this limitation?

DaWei Sep 23rd, 2007 8:51 AM

I pretty sure you can't do that in C++ because of type safety issues. You might have a look at boost::function to see if you can work something out.

Soulstorm Sep 23rd, 2007 9:48 AM

Nah. Boost might help but I really don't want to jump into learning Boost, since I recently began with OpenGL (again)... Thanks, anyway.

Jessehk Sep 23rd, 2007 10:49 AM

I came up with something like this. It's not pretty, and it might not do what you want, but I think it's pretty close. :)

:

#include <iostream>


// Optionally, FunctionA
// could have some internal data that
// helps compute the results of a function call.
// For example, a table lookup functor may store
// a table.
struct FunctionA {
    FunctionA() {}

    // this one will take an int
    void call( int n ) {
        // example
        std::cout << n * n << std::endl;
    }
};

struct FunctionB {
    FunctionB() {}
   
    // this one will take 2 floats
    void call( float a, float b ) {
        std::cout << a * b << std::endl;
    }
};

template <typename FunctionType>
class Test {
    private:
        // mutable because the function might want to
        // modify its internal state when called.
        mutable FunctionType fun_;
    public:
        void setFunction( const FunctionType &function ) {
            fun_ = function;
        }
       
        FunctionType &action() { return fun_; }
};

int main() {
    Test<FunctionA> testa;
    testa.setFunction( FunctionA() );
    testa.action().call( 3 );
   
    Test<FunctionB> testb;
    testb.setFunction( FunctionB() );
    testb.action().call( 4.2, 3.6 );
}


The disadvantages I can think of are that you would have to wrap every function in a struct and wouldn't be able to change the function type associated with a class during runtime. You could maybe get around that by writing a copy constructor for Test and when you need to change the function, do something like:

:

Test<FunctionB> tester( tester ); // Where tester is Test<FunctionA>

I don't really know if that is even possible though. :p

Eoin Sep 23rd, 2007 12:18 PM

I know you've already dismissed Boost, but bind from the Boost libraries will allow you to do that. You would be able to use it without learning any other boost libraries.

l2u Sep 23rd, 2007 10:13 PM

You can use boost::bind.

Jessehk Sep 23rd, 2007 10:29 PM

In case Soulstorm doesn't respond, could one of you post an example of what he is describing using Boost.Bind? I'd be really curious. :)

grumpy Sep 24th, 2007 10:38 AM

You might want to look up the notion of "functors" (or "function objects"), as these may provide a solution to the original problem. Practically, a functor may be implemented as a variation of Jessehk's approach, but supplying overloaded versions of operator() that accept the required argument types.

Incidentally, the mathematical notion of a functor (a mapping between categories) is formally related to the notion of a function object support by some languages, but the theory may be a little daunting if you try to use that as a starting point.

Soulstorm Sep 24th, 2007 12:22 PM

I will look at Jessehk's approach at some point later today. Although I doubt if it will prove to be useful for the things I want it to. It tends to do things more complicated if used with OpenGL functions.

Boost::bind may solve the problem, but I want to have as a solution something that doesn't require the programmer to have the boost libraries installed in his/her machine.

Game_Ender Sep 24th, 2007 2:08 PM

Boost.Bind and Boost.Function libraries are header only. You can copy them out of the boost distribution directly into your project. This is allowed and encouraged.

For the complicated use cases there is even a tool which will pull all the other libraries a boost library depends on out as well (Not needed for boost.bind and boost.function). I can't remember the tool off the top of my head though.


All times are GMT -5. The time now is 3:03 AM.

Powered by vBulletin® Version 3.7.0, Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Copyright ©2007 DaniWeb® LLC