Как сохранить функцию в переменной?
Я думаю, что они называются функторами? (это было некоторое время)
В принципе, я хочу сохранить указатель на функцию в переменной, поэтому я могу указать, какую функцию я хочу использовать из командной строки.
все функции возвращаются и принимают те же значения.
unsigned int func_1 (unsigned int var1)
unsigned int func_2 (unsigned int var1)
function_pointer = either of the above?
поэтому я мог бы назвать это, перейдя: function_pointer(my_variable)?
EDIT:
согласно предложению @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
Ответы
Ответ 1
Самый простой способ -
unsigned int (*pFunc)(unsigned int) = func_1;
Это пустой указатель на функцию, который нельзя использовать для указания на что-либо, кроме бесплатной функции.
Вы можете сделать это менее болезненным, если ваш компилятор поддерживает ключевое слово С++ 0x auto
:
auto pFunc = func_1;
В любом случае вы можете вызвать функцию с помощью
unsigned int result = pFunc(100);
Есть много других опций, которые обеспечивают общность, например:
- Вы можете использовать
boost::function
с любым компилятором С++
- С компилятором, реализующим функции С++ 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;
Ответ 2
Нет, они называются указателями функций.
unsigned int (*fp)(unsigned int) = func_1;
Ответ 3
Вы также можете использовать функцию либо из С++ 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);
}
Ответ 4
typedef unsigned int (*PGNSI)(unsigned int);
PGNSI variable1 = func_1;
PGNSI variable2 = func_2;
Ответ 5
unsigned int (* myFuncPointer)(unsigned int) = &func_1;
Однако синтаксис указателей на функции ужасен, поэтому для них typedef
это общее:
typedef unsigned int (* myFuncPointerType)(unsigned int);
myFuncPointerType fp = &func_1;
Ответ 6
Если у вас установлено Boost, вы также можете проверить Функция ускорения.