F
Frederick Gotham
Let's say we want to write a function which calculates the force which
earth's gravity exerts on an object of particular mass at sea level. We
could start off with:
unsigned CalcForce(unsigned const mass)
{
return mass * 9.81; /* Let's ignore the rounding-down */
}
Of course though, C++ has many built-in arithmetic types; we could as
easily have written it as:
double CalcForce(double const mass)
{
return mass * 9.81;
}
or:
long unsigned CalcForce(long unsigned const mass)
{
return mass * 9.81;
}
So this might lead us to write a template function which can deal with any
arithmetic type. We might start off with:
template<class T>
T CalcForce(T const mass)
{
return mass * 9.81;
}
The problem with this, however, is that it is TOO generic -- it could be
passed anything from a pointer to an std::string! In an attempt to restrict
the possibilities, maybe we could try:
#define COMPASS /* Compile-time assertion */
#include <limits>
template<class T>
T CalcForce(T const mass)
{
COMPASS(std::numeric_limits<T>::is_specialized);
return mass * 9.81;
}
Do you think this is a wise way to write a generic function which deals
with numbers?
Lastly, let's say that we want this function to work with user-defined
arithmetic types also, such as a BigNum library. Should any such classes be
expected to have a specialisation of "numeric_limits"?
earth's gravity exerts on an object of particular mass at sea level. We
could start off with:
unsigned CalcForce(unsigned const mass)
{
return mass * 9.81; /* Let's ignore the rounding-down */
}
Of course though, C++ has many built-in arithmetic types; we could as
easily have written it as:
double CalcForce(double const mass)
{
return mass * 9.81;
}
or:
long unsigned CalcForce(long unsigned const mass)
{
return mass * 9.81;
}
So this might lead us to write a template function which can deal with any
arithmetic type. We might start off with:
template<class T>
T CalcForce(T const mass)
{
return mass * 9.81;
}
The problem with this, however, is that it is TOO generic -- it could be
passed anything from a pointer to an std::string! In an attempt to restrict
the possibilities, maybe we could try:
#define COMPASS /* Compile-time assertion */
#include <limits>
template<class T>
T CalcForce(T const mass)
{
COMPASS(std::numeric_limits<T>::is_specialized);
return mass * 9.81;
}
Do you think this is a wise way to write a generic function which deals
with numbers?
Lastly, let's say that we want this function to work with user-defined
arithmetic types also, such as a BigNum library. Should any such classes be
expected to have a specialisation of "numeric_limits"?