Читая это объявление изнутри наружу, можно заметить у f1
список параметров, таким образом, f1
— это функция. Имени f1
предшествует знак *
, следовательно, функция f1()
возвращает указатель. У типа самого указателя тоже есть список параметров, таким образом, указатель указывает на функцию. Эта функция возвращает тип int
.
И наконец, следует обратить внимание на то, что объявления функций, которые возвращают указатель на функцию, можно упростить при помощи замыкающего типа возвращаемого значения (см. раздел 6.3.3):
auto f1(int) -> int (*)(int*, int);
auto
и decltype
для типов указателей на функцииЕсли известно, какую функцию (функции) следует возвратить, можно использовать спецификатор decltype
для упрощения записи типа возвращаемого значения в виде указателя на функцию. Предположим, например, что имеются две функции, обе возвращают тип string::size_type
и имеют два параметра типа const string&
. Можно написать третью функцию, которая получает параметр типа string
и возвращает указатель на одну из следующих двух функций следующим образом:
string::size_type sumLength(const string&, const string&);
string::size_type largerLength(const string&, const string&);
// в зависимости от значения строкового параметра функция getFcn
// возвращает указатель на sumLength или largerLength
decltype(sumLength) *getFcn(const string &);
Единственная сложность в объявлении функции getFcn()
— это необходимость помнить, что при применении спецификатора decltype
к функции она возвращает тип функции, а не указатель на тип функции. Чтобы получить указатель, а не функцию, следует добавить знак *
.
Упражнение 6.54. Напишите объявление функции, получающей два параметра типа int
, и возвращающей тип int
. Объявите также вектор, элементами которого является тип указателя на эту функцию.
Упражнение 6.55. Напишите четыре функции, которые добавляют, вычитают, умножают и делят два значения типа int
. Сохраните указатели на эти значения в векторе из предыдущего упражнения.
Упражнение 6.56. Обратитесь к каждому элементу вектора и выведите результат.
Резюме
Функции представляют собой именованные блоки действий, применяемые для структурирования даже небольших программ. При их определении указывают тип возвращаемого значения, имя, список параметров (возможно, пустой) и тело функции. Тело функции — это блок операторов, выполняемых при вызове функции. Переданные функции при вызове аргумента должны быть совместимы с типами соответствующих параметров.
В языке С++ функции могут быть перегружены. То есть одинаковое имя может быть использовано при определении разных функций, отличающихся количеством или типами параметров. На основании переданных при вызове аргументов компилятор автоматически выбирает наиболее подходящую версию функции. Процесс выбора правильной версии из набора перегруженных функций называют подбором функции с наилучшим соответствием.
Термины
Автоматический объект (automatic object). Объект, являющийся для функции локальным. Автоматические объекты создаются и инициализируются при каждом обращении и удаляются по завершении блока, в котором они были определены.
Аргумент (argument). Значение, предоставляемое при вызове функции для инициализации соответствующих параметров.
Аргумент по умолчанию (default argument). Значение, определенное для использования, когда аргумент пропущен при вызове функции.
Бесконечная рекурсия (recursion loop). Когда у рекурсивной функции отсутствует условие остановки, она вызывает сама себя до исчерпания стека программы.
Встраиваемая функция (inline function). Функция, тело которой встраивается по месту обращения, если это возможно. Встраиваемые функции позволяют избежать обычных дополнительных затрат, поскольку их вызов заменяет код тела функции.
Вызов по значению (call by value).
Вызов по ссылке (call by reference).
Исполняемый файл (executable file). Файл, содержащий программный код, который может быть выполнен операционной системой.
Классinitializer_list
. Библиотечный класс, представляющий разделяемый запятыми список объектов одинакового типа, заключенный в фигурные скобки.
Компоновка (link). Этап компиляции, на котором несколько объектных файлов объединяются в исполняемую программу.
Локальная переменная (local variable). Переменные, определенные в блоке.