Синтаксис неименованного указателя функции в С++
Я искал самый неприятный сингл, и я наткнулся на что-то вроде этого:
Foo bar(Baz()); // bar is a function that takes a pointer to a function that returns a Baz and returns a Foo
Это сильно отличается от типичного синтаксиса return-type(*name)(parameters)
. В скобках представлены скобки для списка параметров или они для имени?
Ответы
Ответ 1
Полностью явный вид:
Foo bar(Baz f());
bar
- это функция, которая принимает один параметр f
, который является функцией (без аргументов), возвращающей Baz
.
Без указания параметра:
Foo bar(Baz ());
Причина bar
заканчивает принимать указатель на функцию в том, что функции не могут быть переданы по значению, так объявить параметр как функция автоматически затухает его в указатель. Вышеуказанное выражение эквивалентно:
Foo bar(Baz (*)());
// or:
Foo bar(Baz (*f)()); // with a named parameter
Это похоже на void foo(int [10])
где int [10]
также означает int *
в списке параметров.
Ответ 2
В декларации есть два набора круглых скобок. Внешний набор круглых скобок представляет собой список аргументов bar
функций:
Foo bar(Baz());
^ ^
Baz()
в этом объявлении - это тип функции. Скобки в объявлении типа функции ограничивают список аргументов этой функции.
Foo bar(Baz());
^^
Чтобы уточнить: в контексте объявления аргумента функции, тип функции настраивается как указатель на функцию этого типа. Таким образом, декларация фактически эквивалентна:
Foo bar(Baz(*)());
^ ^
Выделенные круглые скобки этого альтернативного указателя аргументов указателя не присутствуют в объявлении "unadjusted".
Соответствующее стандартное правило:
[Dcl.fct]
Тип функции определяется с использованием следующих правил. Тип каждого параметра (включая пакеты параметров функций) определяется из его собственного decl-specifier-seq и declarator. После определения типа каждого параметра любой параметр типа "массив T" или типа функции T настраивается как "указатель на T"....
Ответ 3
В скобках представлены скобки для списка параметров или они для имени?
Они предназначены для списка параметров.
Так:
Foo bar(Baz());
объявляет функцию, которая принимает единственный параметр функции типа, который возвращает Baz
и не принимает никаких параметров.
Это, по очереди, равно объявлению функции aa, которое принимает единственный параметр указателя типа на функцию, которая возвращает Baz
и не принимает никаких параметров. как (из функции):
Тип каждого параметра функции в списке параметров определяется в соответствии со следующими правилами:
...
3) Если тип - это тип функции F, он заменяется типом "указатель на F"
...