Подтвердить что ты не робот

Тип указателя возвращаемой функции

Часто я нахожу необходимость писать функции, возвращающие указатели на функции. Всякий раз, когда я это делаю, основной формат, который я использую:

typedef int (*function_type)(int,int);

function_type getFunc()
{
   function_type test;
   test /* = ...*/;
   return test;
}

Однако это может стать громоздким при работе с большим количеством функций, поэтому я бы не хотел объявлять typedef для каждого из них (или для каждого класса функций)

Я могу удалить typedef и объявить локальную переменную, возвращаемую функцией: int (*test)(int a, int b);, создавая тело функции следующим образом:

{
     int (*test)(int a, int b);
     test /* = ...*/;
     return test;
}

но тогда я не знаю, что задать для возвращаемого типа функции. Я пробовал:

int(*)(int,int) getFunc()
{
    int (*test)(int a, int b);
    test /* = ...*/;
    return test;
}

но это сообщает о синтаксической ошибке. Как объявить возвращаемый тип для такой функции без объявления typedef для указателя функции. Возможно ли это? Также имейте в виду, что мне известно, что было бы проще объявить typedefs, однако для каждой из функций я очень осторожен, чтобы мой код был таким же чистым и легким, насколько это возможно. Причина, по которой я хотел бы исключить typedefs, заключается в том, что они часто используются только для объявления функций поиска и поэтому кажутся избыточными в коде.

4b9b3361

Ответ 1

int (*getFunc())(int, int) { … }

Ответ 2

Возможно, вы можете сделать что-то вроде:

int foo (int i) {return i*2;}

int (*return_foo()) (char)
{
   return foo;
}

но бог, надеюсь, мне никогда не придется отлаживать код...

Ответ 3

Это глупый пример, но он прост и не дает ошибок. Это просто объявление статических функций:

#include <stdio.h>
#include <stdlib.h>

void * asdf(int);
static int * hjkl(char,float);

main() {
  int a = 0;
  asdf(a);
 }


void * asdf(int a) {return (void *)hjkl; }
static int * hjkl(char a, float b) {int * c; return c;}

Ответ 4

При переносе некоторого C-кода в классы С++ у меня было такое же желание, как и исходный плакат: верните указатель функции из функции, не прибегая к typedef 'прототипу указателя функции. Я столкнулся с проблемой корректности С++ const, которую, как мне казалось, стоит поделить, даже если это немного не по теме (С++), но она напрямую связана с исходным вопросом: синтаксис для возврата указателя функции C, не прибегая к typedef.

В приведенном ниже коде описывается класс A, который хранит указатель на функцию и выставляет его во внешний мир через вызов get_f(). Это функция, которая должна возвращать указатель функции без typedef.

Точка (которая надолго зашла мне в голову) заключалась в том, как объявить, что get_f() является функцией const, то есть не изменяет A.

Код содержит 2 варианта: первый использует typedef для прототипа указателя функции, в то время как второй полностью записывает все. #if переключается между двумя.

#include <iostream>

int my_f(int i)
{
  return i + 1;
}

#if 0 // The version using a typedef'ed function pointer

typedef int (*func_t)(int);

class A
{
public:
  A(func_t f) : m_f(f) {}
  func_t get_f() const { return m_f; }

private:
  func_t m_f;
};

int main(int argc, char *argv[])
{
  const A a(my_f);
  std::cout << "result = " << a.get_f()(2) << std::endl;
}

#else // The version using explicitly prototyped function pointer    

class A
{
public:
  A(int (*f)(int)) : m_f(f) {}
  int (*get_f() const)(int) { return m_f; }

private:
  int (*m_f)(int);
};

int main(int argc, char *argv[])
{
  const A a(my_f);
  std::cout << "result = " << a.get_f()(2) << std::endl;
}

#endif

Ожидаемый/желаемый результат:

result = 3

Ключевым моментом является положение классификатора const в строке:

int (*get_f() const)(int) { return m_f; }

Ответ 5

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

#include <stdio.h>

int (*idputs(int (*puts)(const char *)))(const char *) {
    return puts;
}

int main(int argc, char **argv)
{
    idputs(puts)("Hey!");

    return 0;
}

Ответ 6

Я думаю, у вас есть три варианта:

  • Придерживайтесь typedef. В конце дня, это typedef работу.
  • Возвращает void * и его литье.
  • Пересмотреть свою архитектуру программного обеспечения. Возможно, вы могли бы поделиться с нами тем, что вы пытаетесь достичь, и посмотреть, можем ли мы указать вам на лучшее направление.