#c #pointers
Вопрос:
Скажем, у нас есть 2 функции
foo() { cout << "Hello"; }
foo2() { cout << " wolrd!"; }
как я могу создать массив указателей (скажем a
, b
), a
указывающих на foo()
и b
на foo2()
? моя цель состоит в том, чтобы сохранить эти указатели в массиве A, а затем выполнить цикл над A для выполнения этих функций.
Комментарии:
1. Поскольку вы используете C , а не C, используйте
std::function
не необработанные указатели.2. @Jepessen Вам не нужно
std::function
столько времени, сколько требуется. Обычный тип указателя функции также будет работать для данного случая.3. @Jepessen: нам следует избегать необработанного указателя на владение. обычный указатель может быть в порядке.
4. Вы забыли тип возвращаемой функции, какие бы проблемы у вас ни возникали, это, вероятно, связано с тем, что компилятор находится в режиме GNU (или другом несовместимом), а тип по умолчанию
int
.5. @Jarod42
my goal is to store these pointers in an array A, then loop over A to execute these functions.
, на мой взглядstd::function
, является лучшим, более чистым и безопасным решением для достижения его цели. Тогда, очевидно, можно использовать необработанные указатели.
Ответ №1:
Вы можете использовать типизированные указатели функций следующим образом:
using FunPtrType = void(*)();
FunPtrType arr[]{&foo, &foo2};
// or
std::array<FunPtrType, 2> arr2{&foo, &foo2};
// ... do something with the array of free function pointers
// example
for(auto fun: arr2)
fun();
Комментарии:
1. Я бы рекомендовал не использовать псевдонимы типов для указателей. Они делают программу менее очевидной, так как скрывают звездочку.
2. я получаю сообщение «неполный тип недопустим» в строке std::массивlt;FunPtrType, 2gt; arr2{amp;foo, amp;foo2}; есть идеи?
3. а ты
#include lt;arraygt;
? Вам не нужно указывать параметры шаблона, начиная с C 17: godbolt.org/z/jMME54r75 Ах, и вы забыли указать тип возврата ваших функцийfoo()
==gt;void foo()
4. @eerorika (IMO) использование делает типы указателей функций более читаемыми, чем
some retunr type(*)( a lot of arguments)
легко редактируемыми во всей базе кода.5. @eerorika дело стиля. Некоторые могут возразить, что
void (*arr[])() {amp;foo, amp;foo2};
это менее читабельно. Это больше похоже на какую-то лямбду, пострадавшую от транспортного инцидента
Ответ №2:
Существует простая реализация:
#include lt;iostreamgt; #include lt;vectorgt; using namespace std; // Defining test functions void a(){coutlt;lt;"Function A"lt;lt;endl;} void b(){coutlt;lt;"Function B"lt;lt;endl;} int main() { /*Declaring a vector of functions Which return void and takes no arguments. */ vectorlt;void(*)()gt; fonc; //Adding my functions in my vector fonc.push_back(a); fonc.push_back(b); //Calling with a loop. for(int i=0; ilt;2; i ){ fonc[i](); } return 0; }
Ответ №3:
В наши дни нет необходимости в типах, просто используйте auto
.
#include lt;iostreamgt; void foo1() { std::cout lt;lt; "Hello"; } void foo2() { std::cout lt;lt; " world!"; } auto foos = { amp;foo1, amp;foo2 }; int main() { for (auto foo : foos) foo(); }
Ответ №4:
Есть два эквивалентных способа сделать то, что вы хотите:
Способ 1
#include lt;iostreamgt; void foo() { std::cout lt;lt; "Hello"; } void foo2() { std::cout lt;lt; " wolrd!"; } int main() { void (*a)() = foo;// a is a pointer to a function that takes no parameter and also does not return anything void (*b)() = foo2;// b is a pointer to a function that takes no parameter and also does not return anything //create array(of size 2) that can hold pointers to functions that does not return anything and also does not take any parameter void (*arr[2])() = { a, b}; arr[0](); // calls foo arr[1](); //calls foo1 return 0; }
Метод 1 может быть выполнен здесь.
Способ 2
#include lt;iostreamgt; void foo() { std::cout lt;lt; "Hello"; } void foo2() { std::cout lt;lt; " wolrd!"; } int main() { //create array(of size 2) that can hold pointers to functions that does not return anything void (*arr[2])() = { foo, foo2}; arr[0](); // calls foo arr[1](); //calls foo1 return 0; }
Способ 2 может быть выполнен здесь.