Reputation: 9527
I have this code in header
class MyMathUtils {
template <typename T> static bool IsEqual(const T & val1, const T & val2);
};
template <typename T>
bool MyMathUtils::IsEqual(const T & val1, const T & val2)
{
return (val1 == val2);
};
And this in cpp
template <>
bool MyMathUtils::IsEqual<float>(const float & val1, const float & val2)
{
if ((val1 - val2) < -EPSILON) return false;
if ((val1 - val2) > EPSILON) return false;
return true;
}
Problem is, that compiler gives me this error:
MyMath::MyMathUtils::IsEqual(float const &,float const &)" (??$IsEqual@M@MyMathUtils@MyMath@@SA_NABM0@Z) already defined in MyMathUtils.obj; second definition ignored
But if I use the same, but instead of float I put double, it is compiled correctly. What is incorrect here, that I am missing?
Upvotes: 0
Views: 260
Reputation: 254631
You need to declare the specialisation in the header.
namespace MyMathUtils {
// generic template (shouldn't be static)
template <typename T> bool IsEqual(const T & val1, const T & val2);
// explicit specialisation
template <> bool IsEqual<float>(const float & val1, const float & val2);
// alternatively, overloading would be simpler
bool IsEqual(float, float);
};
(I took the liberty of changing this to a namespace, not a class, since that makes much more sense. If you really do want it to be a class for some reason, you'll have to declare the specialisation in the namespace outside.)
Otherwise, using it in other translation units will cause it to be instantiated from the generic template, since the compiler doesn't know that the explicit specialisation exists. This causes multiple definitions.
Upvotes: 1