Изучаю C++. остановился на теме "Указатели на функции".
Есть код работающий.
#include <iostream>
using namespace std;
double add(double, double);
double multi(double, double);
double divorce(double, double);
const double* calculate(double, double, double (*pr[3])(double, double));
double (*pf[3])(double, double) = {&add, &multi, &divorce};
int main()
{
const double* q = calculate(2.5, 10.4, pf);
cout << endl;
for (int i = 0; i < 3; ++i)
{
cout << q[i] << endl;
}
return 0;
}
double add(double x, double y)
{
return x + y;
}
double multi(double x, double y)
{
return x * y;
}
double divorce(double x, double y)
{
return x / y;
}
const double* calculate(double x, double y, double (*pr[3])(double, double))
{
auto* ptr = new double[3];
for (int i = 0; i < 3; ++i)
{
ptr[i] = (*pr[i])(x, y);
}
return ptr;
}
Если поменять строки
double add(double, double);
double multi(double, double);
double divorce(double, double);
на
const double add(double, double);
const double multi(double, double);
const double divorce(double, double);
то тогда выражение
double (*pf[3])(double, double) = {&add, &multi, &divorce};
нужно поменять на
double (*pf[3])(double, double) = {add, multi, divorce};
Почему?
Да и еще один вопрос.
Объясните разницу между
const double (*pf[3])(double, double)
и double (*pf[3])(double, double)
Менять необходимо, так как сигнатура функции double add(double, double); не соответствует сигнатуре функции const double add(double, double);. Различие заключается в наличии const-квалификатора для возвращаемого значения. Причем для простых типов наличие этого const-квалификатора вообще-то не имеет смысла, а для объектов может быть большая разница, например если возвращать просто std::string x(void), то можно написать вот так x().append("oops");.
У Вас в коде два разных типа, с одной стороны Вы объявляете массив, в который можно помещать объекты такого типа: double(*)(double, double), с другой Вы пытаетесь поместить в этот массив функцию add (к примеру), а тип этого выражения будет такой: const double(*)(double, double). Разумеется, что это два разных типа, и Вы не можете просто взять и поместить объект одного типа в массив, который содержит объекты другого типа.
Можно использовать reinterpret_cast, если уж очень хочется, но последствия такого решения всегда лежат на программисте.
Современные инструменты для криптотрейдинга: как технологии помогают принимать решения
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости