Let\'s start with this demo
#include
using namespace std;
template
void abs(T number)
{
if (number < 0)
numbe
There is an abs function built-in to the standard library:
int abs ( int n );
long abs ( long n );
The compiler is going to use these versions in preference to your templated function since non-templated functions are more specific than templated functions, and thus take precedence in function overload resolution.
I recommend that you rename your abs
function to something else to fix this.
As a side note, this might be questionable behavior on the part of your standard library implementation. It appears that #include <iostream>
is pulling in a non-std
-namespaced declaration of abs
and it probably shouldn't be doing that. If you switch to C-style printfs then your program works fine without having to rename anything (at least on my platform, that is).
#include <stdio.h>
template <class T>
void abs(T number)
{
if (number < 0)
number = -number;
printf("The absolute value of the number is %g\n", (double) number);
return;
}
int main()
{
int num1 = 1;
int num2 = 2;
double num3 = -2.1333;
float num4 = -4.23f;
abs(num1);
abs(num2);
abs(num3);
abs(num4);
return 0;
}
I don't recommend that as a solution, just as a curiosity.
There is also a standard library function, std::abs
, which is declared in <cstdlib>
(int
and long
overloads) and <cmath>
(float
, double
, and long double
overloads).
<iostream>
may include either of these headers. If it does, then the std::abs
name is brought into the global namespace because of your use of using namespace std;
During overload resolution, if a nontemplate function has parameters of types that exactly match the types of the arguments, function templates of the same name will not be considered (and in general, nontemplate functions are preferred to function templates).
In your example, you say that your abs
is being called for the two floating point values, but not for the integers. I would guess that your implementation is including <cstdlib>
but not <cmath>
.
You can remove the using namespace std;
from your program, which should resolve the problem. Some implementations (e.g., Microsoft Visual C++) also place the C standard library names in the global namespace, so this may not work.
You can force your function template to be called by explicitly only allowing function templates to be matched during overload resolution:
abs<>(num1);
It is probably just easier to rename your function to something else.
Introduce your own namespace
#include <iostream>
#include <cstdlib> // just for testing ADL of 'abs'
namespace ns // introduce namespace
{
template<class T>
void abs(T number)
{
if (number < 0)
{
number = -number;
}
std::cout << "The absolute value of the number is " << number << std::endl;
}
}
int main()
{
int num1 = 1;
int num2 = 2;
double num3 = -2.1333;
float num4 = -4.23f;
using ns::abs; // use abs from the namespace just introduced above
abs(num1);
abs(num2);
abs(num3);
abs(num4);
return 0;
}
Get rid of the using namespace std
.. it's providing a more specific function.