Почему cmath не является шаблонами pow и sqrt?

Любопытно, почему std::sqrt и std::pow перегружены только для одного типа параметра? Почему они не реализованы как шаблоны функций/функторов?


person Maestro    schedule 10.02.2021    source источник
comment
Под одним типом вы подразумеваете, что каждая перегрузка предназначена для одного типа, или вы имеете в виду, что существует только одно объявление для типа double? Существуют перегрузки для float, double и long double (см. мой ответ).   -  person Keith Thompson    schedule 11.02.2021


Ответы (2)


Они перегружены для типов float, double и long double.

Других типов с плавающей запятой не существует, поэтому в более общем решении с использованием шаблонов не будет преимущества.

Заголовок C++ <cmath> почти, но не совсем копия заголовка C <math.h>.

В C нет перегрузки, поэтому он предоставляет три разные функции извлечения квадратного корня:

float sqrtf(float arg);
double sqrt(double arg);
long double sqrtl(long double arg);

и аналогично для других функций с плавающей запятой.

<cmath> C++ предоставляет эти функции и перегруженные версии sqrt для всех трех типов с плавающей запятой.

Вот пример, демонстрирующий это:

#include <iostream>
#include <iomanip>
#include <cmath>

int main() {
    auto f = std::sqrt(2.0F);
    auto d = std::sqrt(2.0);
    auto ld = std::sqrt(2.0L);
    std::cout << std::setprecision(64);
    std::cout << ' ' << sizeof f << ' '  << f  << '\n';
    std::cout << ' ' << sizeof d << ' '  << d  << '\n';
    std::cout        << sizeof ld << ' ' << ld << '\n';
}

Вывод в моей системе, демонстрирующий разный размер и точность для каждого вызова:

 4 1.41421353816986083984375
 8 1.4142135623730951454746218587388284504413604736328125
16 1.4142135623730950487637880730318329369765706360340118408203125
person Keith Thompson    schedule 10.02.2021

'c' в <cmath> буквально означает, что это набор библиотечных функций C. По аналогии, <stdio.h> может быть включено в C++ как <cstdio> и т. д., а поскольку в C нет шаблонов, то и в <cmath> ничего нет.

Помимо этого, что даст вам параметризация типа? Эти функции принимают и возвращают double, которые вы всегда можете преобразовать в простые int или float, если вам это нужно.

Я исправлен во втором пункте: как отмечают М.А. и Франсуа Андрие, бывают ситуации, когда это было бы полезно. Тем не менее, я считаю, что ответ остается в силе в том, что касается <cmath>.

person dandan78    schedule 10.02.2021
comment
В случае std::pow целочисленное возведение в степень может быть реализовано более эффективно (+точно), поэтому приведение к двойному значению и обратно не будет идеальным. - person Mansoor; 11.02.2021
comment
Хорошо, но я готов поспорить, что большинство FPU в настоящее время делают это аппаратно и что вы вряд ли найдете эквивалент, работающий с целыми числами. - person dandan78; 11.02.2021
comment
@ dandan78 Тот факт, что такой шаблон был фактически добавлен в язык, является убедительным доказательством того, что разумно хотеть шаблонную версию функции. - person François Andrieux; 11.02.2021