Разница между функциями и указателями функций в качестве аргументов

Это довольно простой вопрос, который вызывает у меня некоторое любопытство. Рассмотрим следующий фрагмент кода:

#include <iostream>

int three()
{
    return 3;
}

void foo(int func(void))
{
    std::cout << func() << std::endl;
}

void bar(int (*func)(void))
{
    std::cout << func() << std::endl;
}

int main()
{
    foo(three);
    bar(three);
    return 0;
}

// output:
// 3
// 3

Как видите, у нас есть две функции, которые принимают другую функцию в качестве единственного аргумента. Однако прототипы функций для них различаются. В основном у нас есть void foo(int func(void)) и void bar(int (*func)(void)). На первый взгляд кажется, что foo берет саму функцию, а bar берет указатель на функцию.

Однако они оба дают одинаковые результаты, имеют одно и то же тело и вызываются совершенно одинаковым образом.

Мой вопрос в том, есть ли на самом деле скрытая разница между foo и bar? Это просто необязательный синтаксис в C++? Является ли один из двух случаев «плохим стилем» в С++?

Если мой компилятор играет роль, я использую Visual Studio 2010.


person Zeenobit    schedule 21.10.2011    source источник
comment
Это не имеет ничего общего с visual-studio-2010.   -  person overcoder    schedule 21.10.2011
comment
@overcoder: удалил тег. :)   -  person Zeenobit    schedule 21.10.2011


Ответы (1)


Разницы нет: типы foo и bar одинаковы: int(int(*)()).

Не существует такого понятия, как параметр функционального типа: когда параметр появляется с синтаксисом функционального типа (например, int func(void)), он преобразуется в соответствующий тип указателя на функцию (например, int (*func)(void)).

Преобразование похоже на то, как параметр, объявленный с синтаксисом массива (например, int a[]), преобразуется в соответствующий тип указателя (int* a).

person James McNellis    schedule 21.10.2011