Почему выдает ошибку связанную с указателем на функцию?
Есть три функции:
const double *f1(const double ar[], int n);
const double *f2(const double ar[], int n);
const double *f3(const double ar[], int n);
Два указателя на функцию:
const double *(*p1)(const double *, int) = f1;
auto p2 = f2;
Работа с указателями:
cout << (*p1)(av, 3) << ": " << *(*p1)(av, 3) << endl;
cout << p2(av, 3) << ": " << *p2(av, 3) << endl;
Использую два типа работы с указателями: (*p1)(av, 3) и p2(av, 3) и никаких ошибок не выдает.
Но при работе с массивами указателей на функции почему-то это так не работает:
const double *(*pa[3])(const double *, int) = { f1, f2, f3 }; //Массив из трех указателей
cout << pa[0](av, 3) << ": " << *pa[0](av, 3) << endl;
cout << (*pa)[0](av, 3) << ": " << *(*pa)[0](av, 3) << endl; //Выдает ошибку. Почему?
Здесь я также использую две формы работы с указателями, но с массивом генерируется ошибка.
Второй похожий пример:
const double * (*(*pd)[3])(const double *, int) = &pa;
const double *pdb = (*pd)[0](av, 3);
const double *pdb = pd[0](av, 3); //Снова выдает ошибку. По идее я использую вторую форму обращения к
//указателя на функцию и все должно работать, но почему-то генерируется ошибка.
Итак вопрос: почему при работе с указателем на функцию работают две формы обращения к указателям, а при работе с массивом указателей на функции или с указателем на массив указателей на функции что-то идет не так?
P.S. Просьба: по возможности дать ответ применительно к примерам выше.
Заранее спасибо
Ответы (2 шт):
Напишите
cout << (pa[0])(av, 3) << ": " << *(pa[0])(av, 3) << endl;
const double *pdb = (*pd[0])(av, 3);
В записи (*pa)[0](av, 3) массив преобразовывается в указатель на первый элемент, после разыменования этого указателя получается ссылка на указатель на функцию, затем к этому указателю на функцию применяется оператор индексирования, что собственно уже запрещено.
А надо было сначала применить к массиву оператор индексирования: (*(pa[0]))(av, 3). А в случае с pd надо сначала разыменовать указатель на массив.
А еще лучше не морочить себе голову скобками и разыменованиями и использовать std::invoke
::std::invoke(pa[0], av, 3);