|
From: 3DCoderGuy on 9 May 2008 11:44 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 9 May 2008 12:05 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 9 May 2008 12:12 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 9 May 2008 12:21 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 9 May 2008 12:29
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 |