Хобрук: Ваш путь к мастерству в программировании

Как сохранить функцию в переменной?

Кажется, они называются функторами? (Прошло много времени)

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

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

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

Конфиг.cpp:

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

хэши.ч:

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

hashes.cpp:

just implements the functions in the header

основной.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
07.04.2011

Ответы:


1

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

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;
07.04.2011
  • В c++0x можно использовать auto ;-) 07.04.2011
  • как назначить функцию pFunc и как вызвать pFunc? 07.04.2011
  • @DerNalia: есть код как для назначения, так и для вызова функции. 07.04.2011
  • Итак, тогда... Я думаю, что моя ошибка связана с тем, как я использую классы. Я отмечу это как ответ и проголосую за вас. Если бы вы могли помочь моей проблеме с классами, это было бы здорово. 07.04.2011

  • 2

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

    unsigned int (*fp)(unsigned int) = func_1;
    
    07.04.2011
  • Примечание: вы будете называть его (*fp)(my_variable), а не так, как описано в посте. 07.04.2011
  • @Michael: вы можете позвонить с помощью fp(arg), поскольку указатель на функцию был обычной функцией. Попробуйте. 07.04.2011
  • Я думаю, что я действительно близок... однако я получаю символ не найден. Я храню указатель на функцию в другом классе... Я добавлю немного кода. 07.04.2011
  • @DerNalia: это потому, что вы объявляете указатель функции как переменную экземпляра, а не статический член, поэтому вы не можете установить его в самом классе. Если вы хотите, чтобы это была настройка для всего класса, для синтаксического здравомыслия я бы набрал тип указателя на функцию, а затем создал статический член с этим typedef для его типа. 07.04.2011
  • что означает типоопределение? (я новичок в C++, если вы не можете сказать ^_~) 07.04.2011
  • Кроме того, я хотел бы выбрать несколько ответов как правильных... потому что... это несправедливо по отношению к людям, понимаете? 07.04.2011

  • 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);
    }
    
    07.04.2011
  • Это все немного сбивает с толку... Итак, если у меня есть функция с именем my_function, как мне назначить ее переменной, чтобы я мог вызвать ее, выполнив function_pointer(variable)? 07.04.2011
  • Я понимаю ваш код, но можете ли вы сказать мне typedef boost: function‹int(int)› Function_t работает или как вы используете ‹int(int)›? 23.12.2016

  • 4

    Из С++ 11 вы можете использовать std::function для хранения функций. Чтобы сохранить функцию, вы используете ее как follsonig:

    std::function‹возвращаемый тип(тип(ы) параметра)>

    как пример вот это:

    #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);
    }
    
    04.07.2018
  • Почему main имеет void и ничего не возвращает? (В остальном отличный ответ) 21.02.2020
  • В C, если у вас есть main(), он будет принимать столько аргументов, сколько вы хотите, и в некоторых случаях он будет хранить эти аргументы до тех пор, пока программа работает. void guaranties main автоматически отбрасывает все аргументы, которые вы ему даете. 22.02.2020
  • вот хорошо прочитано. geeksforgeeks.org/difference-int-main-int-mainvoid 22.02.2020

  • 5
    unsigned int (* myFuncPointer)(unsigned int) = &func_1;
    

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

    typedef unsigned int (* myFuncPointerType)(unsigned int);
    myFuncPointerType fp = &func_1;
    
    07.04.2011
  • Это все немного сбивает с толку.... Итак, если у меня есть функция с именем my_function, как мне назначить ее переменной, чтобы я мог вызвать ее, выполнив function_pointer(variable) спасибо. знак равно 07.04.2011

  • 6

    Вы можете сохранить функцию в переменной в С++ таким образом

    auto function_name = [&](params){
        statements 
    };
    
    
    auto add = [&](int a,int b){
        return a+b;
    };
    cout<<add(5,6);
    
    25.04.2021

    7

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

    07.04.2011
  • Вы видели примеры, приведенные в ссылке Boost Function? Например, в вашем случае функции принимают unsigned int и возвращают unsigned int. Если вы используете функцию Boost, вам придется объявить boost::function1<unsigned int, unsigned int> f;. Это означает, что вы объявляете объект функции f, который возвращает unsigned int (первый параметр шаблона) и принимает unsigned int в качестве параметра (второй параметр шаблона). Итак, если у вас есть функция типа void fx(int, int), вы объявляете объект функции как boost::function2<void, int, int> f. 07.04.2011
  • Приведенный выше комментарий касается того, как объявить объект функции. Затем в коде, где вы хотите его использовать, все, что вам нужно сделать, это f = &your_function;. Затем на месте вызова вы просто вызываете f(3). См. учебник по функции Boost. Это очень понятно. 07.04.2011
  • @NullVoxPopuli: ответ недействителен только потому, что синтаксис в статье сбивает с толку. 14.09.2016

  • 8
  • Я не понимаю, могу ли я использовать указатель как класс, где первая и вторая переменные хранят другие функции? 23.12.2016
  • Новые материалы

    5 проектов на Python, которые нужно создать прямо сейчас!
    Добро пожаловать! Python — один из моих любимых языков программирования. Если вы новичок в этом языке, перейдите по ссылке ниже, чтобы узнать о нем больше:

    Dall-E 2: недавние исследования показывают недостатки в искусстве, созданном искусственным интеллектом
    DALL-E 2 — это всеобщее внимание в индустрии искусственного интеллекта. Люди в списке ожидания пытаются заполучить продукт. Что это означает для развития креативной индустрии? О применении ИИ в..

    «Очень простой» эволюционный подход к обучению с подкреплением
    В прошлом семестре я посетил лекцию по обучению с подкреплением (RL) в моем университете. Честно говоря, я присоединился к нему официально, но я редко ходил на лекции, потому что в целом я нахожу..

    Освоение информационного поиска: создание интеллектуальных поисковых систем (глава 1)
    Глава 1. Поиск по ключевым словам: основы информационного поиска Справочная глава: «Оценка моделей поиска информации: подробное руководство по показателям производительности » Глава 1: «Поиск..

    Фишинг — Упаковано и зашифровано
    Будучи старшим ИТ-специалистом в небольшой фирме, я могу делать много разных вещей. Одна из этих вещей: специалист по кибербезопасности. Мне нравится это делать, потому что в настоящее время я..

    ВЫ РЕГРЕСС ЭТО?
    Чтобы понять, когда использовать регрессионный анализ, мы должны сначала понять, что именно он делает. Вот простой ответ, который появляется, когда вы используете Google: Регрессионный..

    Не зря же это называют интеллектом
    Стек — C#, Oracle Опыт — 4 года Работа — Разведывательный корпус Мне пора служить Может быть, я немного приукрашиваю себя, но там, где я живу, есть обязательная военная служба на 3..