ssell
ssell

Reputation: 6597

C++ : Pass Dynamic Functions and Store Functions?

I have two questions regarding functions in C++: can you dynamically declare a function when passing it as a reference, and is it possible to store functions to use later?

Passing Dynamic Function?

My question may not be worded perfectly clear, but what I mean is in Java you quite often see code that looks like:

button.addActionListener( new ActionListener( ) 
{
    public void actionPerformed( ActionEvent e )
    {
        System.out.println( "..." );
    }
} );

or JavaScript:

$( ".class" ).each( function( )
{
    alert( "..." );
} );

While in C++ you are limited to:

void print( )
{
    std::cout << "..." << std::endl;
}

void func( void ( &f )( ) )
{
    f( );
}

// ...

func( print );

and can not do something like

void func( void ( &f )( ) )
{
    f( );
}

// ...

func( void f( ){ ... } );

Is this just a limitation to C++?

Storing Functions?

Is it at all possible to store similar functions into a container to be called later? An example of the idea (which does not work) is:

std::vector< void( ) > storage;

void callMeLater( void ( &f )( ) )
{
    storage.push_back( f );
}

void popFunction( )
{
    void f( ) = storage.pop_back( );
    f( );
}

These ideas both came to me when working on an Event system, to see if my Timer object could also handle delayed functions as well as event calls. As I have never seen these used in any C++ code, I doubt they are possible but would love to be shown otherwise!

Thank you.

Upvotes: 1

Views: 173

Answers (1)

Sebastian Mach
Sebastian Mach

Reputation: 39109

With the current standard, it has become very easy:

#include <functional>

void foo (std::function<float(float,float)> bar) {
    std::cout << bar (0.5, 0.75);

    std::function<float(float,float)> frob = bar;
}

Within the angle brackets you declare the output (a single float in this case) and input (two floats).

You could then call it like this:

float perlin_noise_function (float x, float z) { ... }

class PerlinNoiseFunctor : public std::binary_function<float(float,float)>
{...};

int main () {
    // pass function pointer
    foo (perlin_noise);

    // pass functor
    PerlinNoiseFunctor pnf;
    foo (pnf);

    // pass lambda function
    foo ([] (float x, float z) { ... });
}

You could also replace foo like this:

template <typename F>
void foo (F f) ;

Upvotes: 2

Related Questions