From: 3DCoderGuy on
I'm trying to specialize the operator== for my template, here is my code

#define DOUBLE_EPSILON (1e-6)
#define FLOAT_EPSILON (1e-4f)

bool const operator==(const XYZPoint<T> &xyzTest) const
{
return (
(x == xyzTest.x) &&
(y == xyzTest.y) &&
(z == xyzTest.z)
);
};

template<typename T>
bool const operator==(const XYZPoint<float> &xyzTest) const
{
return (
(x - xyzTest.x < FLOAT_EPSILON) && (x - xyzTest.x > -FLOAT_EPSILON) &&
(y - xyzTest.y < FLOAT_EPSILON) && (y - xyzTest.y > -FLOAT_EPSILON) &&
(z - xyzTest.z < FLOAT_EPSILON) && (z - xyzTest.z > -FLOAT_EPSILON)
);
}

template<typename T>
bool const operator==(const XYZPoint<double> &xyzTest) const
{
return (
(x - xyzTest.x < DOUBLE_EPSILON) && (x - xyzTest.x > -DOUBLE_EPSILON) &&
(y - xyzTest.y < DOUBLE_EPSILON) && (y - xyzTest.y > -DOUBLE_EPSILON) &&
(z - xyzTest.z < DOUBLE_EPSILON) && (z - xyzTest.z > -DOUBLE_EPSILON)
);
}

But when I do this
XYZPoint<double> pnt1(1.0,0.0,1.0);
XYZPoint<double> pnt2(1.0,0.0,2.0);

if (pnt1 == pnt2)
{
...
}

the specialization for <double> is never called.

Can this be done, and what would be the correct syntax?

Thanks
Mark


From: Igor Tandetnik on
3DCoderGuy <nobody(a)nospam.com> wrote:
> I'm trying to specialize the operator== for my template, here is my
> code
> #define DOUBLE_EPSILON (1e-6)
> #define FLOAT_EPSILON (1e-4f)
>
> bool const operator==(const XYZPoint<T> &xyzTest) const

I assume this is a member function inside something like

template <typename T> class XYZPoint {...};

> template<typename T>
> bool const operator==(const XYZPoint<float> &xyzTest) const

This is not a specialization of the above, but an overload. The T here
is unrelated to the T which is the class' template parameter. Further,
this overload will never be selected in practice, because in any natural
invocation syntax, T is non-deducible (it doesn't appear anywhere in the
function signature).

Apparently, you want to specialize a member function of class template.
Such a specialization must go outside the class definition, and looks
like this:

template<>
bool const XYZPoint<float>::operator==(const XYZPoint<float>& xyzTest)
const;

--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925


From: Igor Tandetnik on
3DCoderGuy <nobody(a)nospam.com> wrote:
> template<typename T>
> bool const operator==(const XYZPoint<float> &xyzTest) const
> {
> return (
> (x - xyzTest.x < FLOAT_EPSILON) && (x - xyzTest.x > -FLOAT_EPSILON)
> && (y - xyzTest.y < FLOAT_EPSILON) && (y - xyzTest.y >
> -FLOAT_EPSILON) && (z - xyzTest.z < FLOAT_EPSILON) && (z -
> xyzTest.z > -FLOAT_EPSILON) );
> }

Note that this definition of equality is not transitive - it is possible
to have a==b and b==c but !(a==c). This is not a problem per se, but it
can be quite surprising to many programmers and many library algorithms.
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925


From: 3DCoderGuy on
Igor Tandetnik wrote:
> 3DCoderGuy <nobody(a)nospam.com> wrote:
>> I'm trying to specialize the operator== for my template, here is my
>> code
>> #define DOUBLE_EPSILON (1e-6)
>> #define FLOAT_EPSILON (1e-4f)
>>
>> bool const operator==(const XYZPoint<T> &xyzTest) const
>
> I assume this is a member function inside something like
>
> template <typename T> class XYZPoint {...};
>
>> template<typename T>
>> bool const operator==(const XYZPoint<float> &xyzTest) const
>
> This is not a specialization of the above, but an overload. The T here
> is unrelated to the T which is the class' template parameter. Further,
> this overload will never be selected in practice, because in any natural
> invocation syntax, T is non-deducible (it doesn't appear anywhere in the
> function signature).
>
> Apparently, you want to specialize a member function of class template.
> Such a specialization must go outside the class definition, and looks
> like this:
>
> template<>
> bool const XYZPoint<float>::operator==(const XYZPoint<float>& xyzTest)
> const;
>

Thanks Igor,
VC 2003 doesn't like the syntax you have suggested.
From: 3DCoderGuy on
Igor Tandetnik wrote:
> 3DCoderGuy <nobody(a)nospam.com> wrote:
>> template<typename T>
>> bool const operator==(const XYZPoint<float> &xyzTest) const
>> {
>> return (
>> (x - xyzTest.x < FLOAT_EPSILON) && (x - xyzTest.x > -FLOAT_EPSILON)
>> && (y - xyzTest.y < FLOAT_EPSILON) && (y - xyzTest.y >
>> -FLOAT_EPSILON) && (z - xyzTest.z < FLOAT_EPSILON) && (z -
>> xyzTest.z > -FLOAT_EPSILON) );
>> }
>
> Note that this definition of equality is not transitive - it is possible
> to have a==b and b==c but !(a==c). This is not a problem per se, but it
> can be quite surprising to many programmers and many library algorithms.

I understand some of the issues with floating point number comparisons
(I'm not a mathematician). But I thought that was the whole point of
doing this type of comparison?
If my FLOAT_EPSILON is 1e-4f then am I not helping the comparison to
ignore the floating point issue so that a==b && b==c && a==c.
I'm not trying to land a ship on the moon, but if there is a flaw with
my design please let me know.

Thanks
Mark