Search code examples
c++powsqrtcmath

Why aren't cmath's pow and sqrt templates?


As a matter of curiosity, why are std::sqrt and std::pow overloaded just for a single type of parameter? Why are they not implemented as function/functor templates?


Solution

  • They are overloaded for types float, double, and long double.

    There are no other floating-point types, so there would be no advantage in a more general solution using templates.

    The C++ <cmath> header is almost, but not quite, a copy of C's <math.h> header.

    C doesn't have overloading, so it provides three different square root functions:

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

    and similarly for the other floating-point functions.

    C++'s <cmath> provides those functions and overloaded versions of sqrt for all three floating-point types.

    Here's an example that demonstrates this:

    #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';
    }
    

    The output on my system, demonstrating different size and precision for each call:

     4 1.41421353816986083984375
     8 1.4142135623730951454746218587388284504413604736328125
    16 1.4142135623730950487637880730318329369765706360340118408203125