C ++: передать динамические функции и функции хранения? - PullRequest
1 голос
/ 15 февраля 2012

У меня есть два вопроса относительно функций в C ++: можете ли вы динамически объявить функцию при передаче ее в качестве ссылки, и возможно ли сохранить функции для последующего использования?

Передача динамической функции?

Мой вопрос может быть сформулирован не совсем ясно, но я имею в виду, что на Java вы часто видите код, похожий на:

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

или JavaScript:

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

В то время как в C ++ вы ограничены:

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

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

// ...

func( print );

и не можете делать что-то вроде

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

// ...

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

Это ограничение C ++?

Хранение функций?

Можно ли вообще хранить подобные функции в контейнере, который будет вызван позже?Пример идеи (которая не работает):

std::vector< void( ) > storage;

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

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

Эти идеи пришли ко мне при работе над системой событий, чтобы посмотреть, может ли мой объект Timer также обрабатывать отложенные функции, а также событиязвонки.Поскольку я никогда не видел, чтобы они использовались в каком-либо коде C ++, я сомневаюсь, что они возможны, но хотел бы, чтобы их показывали иначе!

Спасибо.

1 Ответ

2 голосов
/ 15 февраля 2012

С текущим стандартом это стало очень просто:

#include <functional>

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

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

В угловых скобках вы объявляете выходные данные (в данном случае один float) и входные (два float).

Вы можете затем назвать это так:

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) { ... });
}

Вы также можете заменить foo так:

template <typename F>
void foo (F f) ;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...