Search code examples
c++templatesexceptioncmath

<cmath> sqrt function cannot be invoked in my function template


I'm trying to write a function template that receives a number from stdin as argument and performs a square root operation on it, unless it happens to be negative, in which case an exception will be thrown. The main program looks like this:

#include "Sqrt _of_Zero_Exception.h"
#include <iostream>
#include <cmath>
using namespace std;

template <typename T>
const T& sqrtNumber(T&);

int main()
{
    int a, result;
    cout << "Enter number to square root: ";
    while (cin >> a){
        try{
            result = sqrtNumber(a);
            cout << "The square root of " << a << " is " << result << endl;
        } //end try
        catch (SqrtofZeroException &sqrtEx){
            cerr << "An exception occurred: " << sqrtEx.what() << endl;
        } //end catch
    }
    return 0;
}

template <typename T>
const T& sqrtNumber(T& num)
{
    if (num < 0)
        throw SqrtofZeroException();

    return sqrt(num);
}

And this is the header file:

#include <stdexcept>

//SqrtofZeroException objects are thrown by functions that detect attempts to square root negative numbers
class SqrtofZeroException : public std::runtime_error
{
public:
    SqrtofZeroException() //constructor specifies default error message
        : runtime_error("square root on a negative number is not allowed"){}
}; //end class SqrtofZeroException

The program can be compiled on Visual Studio but the <cmath> sqrt function is greyed out when I try to call it in my sqrtNumber function: greyed out sqrt

And the output is wrong when I run the program:sample output

If I change the function template to a normal function that accepts integer arguments, I'm able to call sqrt without any issues. So what exactly is the cause of this behavior? Is there something wrong with the syntax of my function template?


Solution

  • sqrt takes a double as a parameter. It won't let you use templates for that because T can be anything. Since it makes no sense to take the square root of, for example, a pointer, it won't let you use a template for that. Have it take a double, any number can be converted to that.