Синтаксис на указател на различна функция като аргумент на друга функция

int func ()
{
  printf("foo()\n"); 
  return 0;
}

void foo1 (int (*pf)()) { pf(); }
void foo2 (int (pf)()) { pf(); }
void foo3 (int pf()) { pf(); }

int main ()
{
  foo1(func);
  foo2(func);
  foo3(func);
}

Каква е разликата между аргумента, предаден на foo1(), foo2() и foo3().
Всичките 3 синтаксиса компилират добре в g++ и се държи по същия начин. Всичките 3 наричат ​​ли се технически указател на функция?
Маркирани със C, тъй като е приложимо и за това.


person iammilind    schedule 07.04.2013    source източник


Отговори (1)


Между тях няма разлика. Първият аргумент е указател към тип функция, докато другите два са само два начина за запис на един и същ тип функция. Въпреки това, по същия начин, по който аргументите от тип масив се настройват да бъдат указатели, аргументите от тип функция се настройват да бъдат указатели към функции. От C++11 §8.3.5/5:

След определяне на типа на всеки параметър, всеки параметър от тип [...] „функция, връщаща T“ се коригира да бъде [...] „указател към функция, връщаща T,“

Или от C99 §6.7.5.3/8:

Декларация на параметър като „функция, връщаща тип“ трябва да бъде коригирана на „указател към функция, връщаща тип

Така втората и третата декларация на функцията имат своя тип аргумент, коригиран така, че да бъде идентичен с първия.

Обърнете внимание, че можете да поставите колкото искате скоби около идентификатора и той ще бъде от същия тип функция:

void foo2 (int (((((pf)))))()) { pf(); }
person Joseph Mansfield    schedule 07.04.2013
comment
В стандарт C99 еквивалентът е 6.7.5.3 p8. - person Oliver Charlesworth; 07.04.2013
comment
Любопитно е обаче, че първият и вторият пример извеждат различни стойности за typeid(pf).name на MSVC 10. - person Peter R; 07.04.2013
comment
@PeterR Това е интересно. Не съм сигурен какви са правилата за това. - person Joseph Mansfield; 07.04.2013