Передача имени функции в качестве аргумента функции - PullRequest
5 голосов
/ 15 июня 2011

Можно ли передать имя функции (скажем, A) в качестве аргумента другой функции (скажем, B), а затем вызвать функцию A из функции B. То есть имя функции будет сохранено в переменной в B и используя его, вызываем функцию, имя которой находится в переменной. Например, в функции сортировки C ++ первый и второй аргументы являются итераторами, а третий аргумент - именем функции.

Ответы [ 5 ]

8 голосов
/ 15 июня 2011

Вы можете ввести параметр шаблона (здесь Pred) для «всего, что можно вызвать с двумя параметрами»:

template <typename Iter, typename Pred>
void mysort(Iter begin, Iter end, Pred predicate)
{
    --end;
    // ...
        if (predicate(*begin, *end))
        {
            // ...
        }
    // ...
}

Затем вы можете передать либо старые добрые указатели на функции C, либо объекты функций C ++:

bool function(int x, int y)
{
    return x < y;
}

struct function_object
{
    bool operator()(int x, int y)
    {
        return x < y;
    }
};

int main()
{
    int numbers[] = {543, 6542654, 432514, 54, 45, 243};
    mysort(numbers + 0, numbers + 6, &function);
    mysort(numbers + 0, numbers + 6, function_object());
}

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

4 голосов
/ 15 июня 2011

Вы должны прочитать о Функциональные указатели .

3 голосов
/ 15 июня 2011

Да , это не только возможно, но и широко используется.

Технически они известны как функциональные указатели .

Концептуально, они должны иметь механизмы callback .Обратные вызовы могут потребоваться для управляемых событиями программ.Например, вашему приложению может быть интересно узнать, когда нажимается кнопка мыши.В этом случае вы регистрируете свой интерес к базовой платформе для события щелчка мыши и сообщаете ему, какой метод / функцию следует вызывать в вашей программе, чтобы вы могли соответствующим образом выполнить код.

Другой такой случайгде программы имеют асинхронный режим выполнения.Например, в случае, если файл должен быть записан на жесткий диск, это трудоемкий процесс по сравнению с выполнением арифметических вычислений.Таким образом, это может быть случай, когда мы не хотим ждать выполнения вычислений, пока записываем результаты в файл.Программа может просто вызвать функцию write для файла и вернуть и начать вычисления.При вызове этой функции вызывающая сторона может также указать функцию callback .Таким образом, когда файл успешно записывается или завершается неудачей, вызывается функция обратного вызова и сообщается вызываемый .

2 голосов
/ 27 октября 2013

простой пример с указателями функций:

#include <iostream>

int apply(int (*fun)(int,int), int a, int b) {
    return (*fun)(a,b);
}

int add(int a, int b) {return a + b;}
int multiply(int a, int b) {return a * b;}

int main(int argc, const char* argv[]) {
    int added = apply(add, 2, 4);
    int multiplied = apply(multiply, 2, 4);

    std::cout << "added result: " << added << std::endl;
    std::cout << "multiplied result: " << multiplied << std::endl;
}

вывод:

added result: 6
multiplied result: 8
2 голосов
/ 15 июня 2011

Да, это возможно.Технически это не совсем «имя», которое передается, а скорее указатель на переданную функцию.

...