2014-02-18 2 views
1

Я читал учебник Алекс Allain на указатели на функции (http://www.cprogramming.com/tutorial/function-pointers.html), в котором он описывает синтаксис получения аргумента функции, как, например:Два стиля синтаксиса для параметра, берущего функцию?

void doSomething(int (*GetNumber)(Player p) = myFunct) { 

} 

Тогда я читал Accelerated C++, который показывает следующий синтаксис:

map<string, vector<int> > 
xref(istream& in, vector<string> find_words(const string&) = split) { 

} 

Есть ли разница между двумя подходами? То есть, по сравнению с B:

A:

void doSomething(int (*GetNumber)(Player p) = myFunc) { 

} 

B:

void doSomething(int GetNumber(Player p) = myFunc) { 

} 

ответ

2

Здесь есть два разных языка.

Одним из них является, что параметр, который по-видимому, типа функции является корректируется во время компиляции, чтобы указатель на функцию:

После определения типа каждого параметра, любой параметр типа « массив T "или" возвращающая функцию T "настраивается как" указатель на T "или" указатель на функцию возврата T "соответственно.

Это правило, которое делает эти объявления функций:

void foo(void (*p)()); 

и

void foo(void (p)()); 

эквивалент.

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

Именующее выражение типа функции Т может быть преобразованы в prvalue типа «указатель на T.» В результате указатель на функцию.

Учитывая объявление функции:

void func(); 

это правило, что делает все эти вызовы:

foo(&func); 
foo(func); 
foo(*func); 
foo(**func); 

равноценные. В последнем случае выражение func имеет тип функции, поэтому оно преобразуется в указатель. Внутренние * разыменовывают, что указатель, дающий выражение типа функции, который затем является импликацией, снова преобразуется в указатель. И внешний * делает то же самое.

Фактически выражение foo также преобразуется в указатель - это то, что требуется оператору вызова функций в качестве операнда, предшествующего (.

+0

Итак, foo (func) == foo (************ func)? –

+0

@jakeliquorblues: Да. –

4

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

void doSomething(int (*GetNumber)(Player p)); 

void doSomething(int GetNumber(Player p)); 

заявить ту же функцию.

Вы могли бы написать заявления также как

void doSomething(int (*)(Player)); 

void doSomething(int(Player)); 

Это же как эквивалентность следующих деклараций

void f(int a[]); 

и

void f(int *a); 

и

void f(int a[10]); 

и даже

void f(int a[100]); 

Они заявляют, ту же функцию.

+0

Согласен с выше. В примере массива не подразумевается преобразование в тип указателя. – tinlyx

+2

@Dave Вы ошибаетесь относительно массивов. Представленные мной декларации эквивалентны. Например, эти объявления void f (int *); void f (int []); void f (int [10]); объявить ту же функцию. –

+0

@Ting L Вы ошибаетесь. Пример деклараций функций с массивом и указателем объявляет ту же функцию. –

Смежные вопросы