Как мне сохранить функцию в переменной? - PullRequest
16 голосов
/ 07 апреля 2011

Я думаю, их называют функторами?(это было некоторое время)

По сути, я хочу сохранить указатель на функцию в переменной, чтобы я мог указать, какую функцию я хочу использовать из командной строки.

всефункции возвращают и принимают одни и те же значения.

unsigned int func_1 (unsigned int var1)
unsigned int func_2 (unsigned int var1)

function_pointer = either of the above?

, поэтому я мог бы вызвать его, выполнив: function_pointer(my_variable)?

РЕДАКТИРОВАТЬ: согласно предложению @ larsmans, я получил это: Config.h:

class Config
{
public:
    unsigned static int (*current_hash_function)(unsigned int);
};

Config.cpp:

#include "Config.h"
#include "hashes.h"
unsigned static int (*current_hash_function)(unsigned int) = kennys_hash_16;

hashes.h:

unsigned int kennys_hash(unsigned int out);
unsigned int kennys_hash_16(unsigned int out);

hashes.cpp:

just implements the functions in the header

main.cpp:

#include "Config.h"
#include "hashes.h"
// in test_network:
    unsigned int hashed = Config::current_hash_function(output_binary);

//in main():
        else if (strcmp(argv[i], "-kennys_hash_16") == 0)
        {
            Config::current_hash_function = kennys_hash_16;
        }
        else if (strcmp(argv[i], "-kennys_hash_8") == 0)
        {
            Config::current_hash_function = kennys_hash;
        }

ошибка, которую я получаю:

g++ -o hPif src/main.o src/fann_utils.o src/hashes.o src/Config.o -lfann -L/usr/local/lib 
Undefined symbols:
  "Config::current_hash_function", referenced from:
      test_network()     in main.o // the place in the code I've selected to show
      auto_test_network_with_random_data(unsigned int, unsigned int, unsigned int)in main.o
      generate_data(unsigned int, unsigned int, unsigned int)in main.o
      _main in main.o // the place in the code I've selected to show
      _main in main.o // the place in the code I've selected to show
      generate_train_file()     in fann_utils.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
make: *** [hPif] Error 1

Ответы [ 7 ]

17 голосов
/ 07 апреля 2011

Самое простое, что вы можете сделать:

unsigned int (*pFunc)(unsigned int) = func_1;

Это пустой указатель на функцию, который нельзя использовать для указания на что-либо, кроме свободной функции.

Вы можете сделать это меньшеБольно, если ваш компилятор поддерживает ключевое слово C ++ 0x auto:

auto pFunc = func_1;

В любом случае вы можете вызвать функцию с помощью

unsigned int result = pFunc(100);

. Есть много других опций, которые предоставляютуниверсальность, например:

  • Вы можете использовать boost::function с любым компилятором C ++
  • С компилятором, реализующим функции C ++ 0x, вы можете использовать std::function

Они могут использоваться для указания на любую сущность, которая может быть вызвана с соответствующей подписью (на самом деле это объекты, которые реализуют operator(), которые называются функторами).

Обновление (для решения обновленного вопроса))

Ваша непосредственная проблема заключается в том, что вы пытаетесь использовать Config::current_hash_function (который вы объявляете просто отлично), но не можете его определить.

Это определяет глобальный статический указатель на функцию, не связанную счто-нибудь в class Config:

unsigned static int (*current_hash_function)(unsigned int) = kennys_hash_16;

Это то, что вам нужно вместо этого:

unsigned int (*Config::current_hash_function)(unsigned int) = kennys_hash_16;
5 голосов
/ 07 апреля 2011

Вы также можете использовать функцию из C ++ 0x или Boost.Это будет

boost::function<int(int)>

, а затем используйте bind для привязки вашей функции к этому типу.

Посмотрите здесь и здесь

Хорошо, вот пример.Я надеюсь, что это помогает.

int MyFunc1(int i)
{
    std::cout << "MyFunc1: " << i << std::endl;
    return i;
}

int MyFunc2(int i)
{
    std::cout << "MyFunc2: " << i << std::endl;
    return i;
}

int main(int /*argc*/, char** /*argv*/)
{
    typedef boost::function<int(int)> Function_t;

    Function_t myFunc1 = boost::bind(&MyFunc1, _1);
    Function_t myFunc2 = boost::bind(&MyFunc2, _1);

    myFunc1(5);
    myFunc2(6);
}
5 голосов
/ 07 апреля 2011

Нет, это так называемые указатели функций.

unsigned int (*fp)(unsigned int) = func_1;
3 голосов
/ 07 апреля 2011
typedef unsigned int (*PGNSI)(unsigned int);

PGNSI variable1 = func_1;
PGNSI variable2 = func_2;
2 голосов
/ 04 июля 2018

В C ++ 11 вы можете использовать std::function для хранения функций. Для сохранения функции вы используете это как follsonig:

std :: function <<em> тип возвращаемого значения ( тип (ы) параметров )>

в качестве примера вот оно:

#include <functional>
#include <iostream>

int fact (int a) {
    return a > 1 ? fact (a - 1) * n : 1;
}

int pow (int b, int p) {
    return p > 1 ? pow (b, p - 1) * b : b;
}

int main (void) {
    std::function<int(int)> factorial = fact;
    std::function<int(int, int)> power = pow;

    // usage
    factorial (5);
    power (2, 5);
}
1 голос
/ 07 апреля 2011
unsigned int (* myFuncPointer)(unsigned int) = &func_1;

Однако синтаксис для указателей на функции ужасен, поэтому typedef них часто встречаются:

typedef unsigned int (* myFuncPointerType)(unsigned int);
myFuncPointerType fp = &func_1;
0 голосов
/ 07 апреля 2011

Если у вас установлено Boost , вы также можете проверить Функция Boost .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...