Frederick Gotham wrote:
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:
You can't pass anything. If you specialize it for anything that has not an
adequate operator * it will not compile. The problem is that the error
message can be difficult to understand, but there are ways to work around
that. There is paper about this in Stroustrup's web, for example.
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"?
If you write code like this you are effectively expecting it. I see one
problem with this approach. One programmer may want to use your function
with a third part BigNum class that does not have that specialization. No
problem, they say, I can write it on my own. Later, a new version of the
BigNum class is released, and now it has the specialization of
numeric_limits. The program must be adapted, or must use conditional code
to be able to compile with any BigNum version.
IMO is more practical to check only for what you need: the availability of
an adequate operator *, in this case.
--
Salu2