Re[4]: char *(*(**foo[][8])())[]; - за сколько распарсите?
От: rg45 СССР  
Дата: 07.05.23 10:48
Оценка:
Здравствуйте, Shmj, Вы писали:

S>В С++ много неочевидных моментов, связанных с декларированием сложных вещей. К примеру, пока не увидел какая сигнатура у функции, возвращающей указатель на другую функцию — никогда бы сам не догадался.


На самом деле, ничего особенно сложного нет, нужно знать лишь пару несложных принципов. Первое, что нужно знать — результатом функции не может быть другая функция или массив, но результатом может быть указатель на функцию или массив. Второе, что нужно знать — для того, чтобы объявить указатель на функцию или массив, нужно использовать дополнительные круглые скобки, которыми мы как-бы присоединим символ указателя к имени массива или функции. Без этих дополнтительных круглых скобок символ указателя будет относиться либо к результату функции, либо к элементу массива.

Конструирование сложного объявления проще всего выполнять последовательно, добавляя новые синтаксические элементы непосредственно слева или справа от имени. Например, имеем изначально простое объявление:

Функция, принимающая строку и возвращающая число:
int foo(const char*);


Указатель на функцию, принимающую строку и возвращающую число (используем дополнительные круглые скобки):
int (*foo)(const char*);


Массив указателей на функции принимающие строку, и возвращающие число (добавляем квадратные скобки с размерностью массива сразу справа от имени):
int (*foo[42])(const char*);


Указатель на массив указателей на функции принимающие строку, и возвращающие число (опять используем дополнительные круглые скобки)
int (*(*foo)[42])(const char*);


Функция, принимающая double, возвращающая указатель на массив указателей на функции принимающие строку, и возвращающие число
(просто добавляем справа от имени декларации список формальных параметров в круглых скобках):
int (*(*foo(double))[42])(const char*);


Указатель на функцию, принимающую double, возвращающую указатель на массив указателей на функции принимающие строку, и возвращающие число
int (*(*(*foo)(double))[42])(const char*);


Анализ выполняется в обратном порядке, начиная от имени объявления.

Сложнее всего, когда имя в объявлении опущено и найти его не всегда просто:
using FooPtr = int (*(*(*)(double))[42])(const char*);

Тут уже нужно иметь некоторую сноровку, чтобы быстро находить точку отсчета, от которой следует проводить разбор.

Но на практике таких многоэтажных объявлений лучше вообще избегать, используя using или typedef.
--
Не можешь достичь желаемого — пожелай достигнутого.
Отредактировано 07.05.2023 11:16 rg45 . Предыдущая версия . Еще …
Отредактировано 07.05.2023 11:03 rg45 . Предыдущая версия .
Отредактировано 07.05.2023 10:58 rg45 . Предыдущая версия .
Отредактировано 07.05.2023 10:56 rg45 . Предыдущая версия .
Отредактировано 07.05.2023 10:52 rg45 . Предыдущая версия .
Отредактировано 07.05.2023 10:49 rg45 . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.