   Operator Overloaded Sub Objects
  I seem to be having some trouble with objects that are templated and have overloaded operators as being members of another object.  For example, I have a 3D point object, that holds the point/particles (X,Y,Z) position.  It is templated to support different coordinate storage types (float, double, int).  If I want to create a vector between the two points, I subtract the point a from point b and the result is then stored in a vector object, which is also templated.  This works fine.Now, let's say I have a triangle object, where the I have points A,B,C.  Points A,B, and C are of the point object type mentioned above.  When I trying to perform the same subtraction to create a vector between the two points, the compiler generates an error stating that it cannot find a suitable subtraction operator method to handle the situation.So given:template<class T_POINT_TYPE>// 3D point objectstruct G_POINT{T_POINT_TYPE X;T_POINT_TYPE Y;T_POINT_TYPE Z;G_POINT(void) : X(0), Y(0), Z(0) { /* Empty */ }G_POINT(const G_POINT<T_POINT_TYPE> &New) : X(New.X), Y(New.Y), Z(New.Z) { /* Empty */ }G_POINT(const T_POINT_TYPE Init_X, const T_POINT_TYPE Init_Y, const T_POINT_TYPE Init_Z) : X(Init_X), Y(Init_Y), Z(Init_Z) { /* Empty */ }const G_POINT &operator=(const G_POINT<G_Float> &New) {X = New.X; Y = New.Y; Z = New.Z; return *this;}const G_POINT &operator-(const G_POINT<G_Float> &Right) {X -= Right.X; Y -= Right.Y; Z -= Right.Z; return *this;}};struct G_TRIANGLE{   G_POINT<G_Float> A;   G_POINT<G_Float> B;   G_POINT<G_Float> C;};This works:int func(void){   G_POINT Point_A(4.0, 5.0, 6.0);   G_POINT Point_B(1.5, 2.5, 3.5);   G_VECTOR<G_Float> Vector_A = Point_B - Point_A;}But this does not:int func(G_TRIANGLE &Triangle){   G_VECTOR<G_Float> Vector = Triangle.B - Triangle.A;}Any ideas as to why the operators are not working the same when objects are sub objects?[Edited by - Daishim on September 5, 2006 8:40:42 PM]
Triangle.A and Triangle.B are both of type G_POINT<G_Float>. The result of G_POINT<G_Float>::operator -(const G_POINT<G_Float> &) is a G_POINT<G_Float>, but you assign it to a variable of type G_VECTOR<G_Float>.Do your G_VECTOR<G_Float> class have a constructor taking a G_POINT<G_Float>?   ;  Yes.  I goofed on the example, the first working example should be a vector that it is assigned to also, which does work.   ;  It would help if you posted the error.;const G_POINT &operator-(const G_POINT<G_Float> &Right) {X -= Right.X; Y -= Right.Y; Z -= Right.Z; return *this;}What you are doing above is often known as "evil".Your operator- is non-const, and behaves like an operator-=.To fix:const G_POINT &operator-=(const G_POINT<G_Float> &Right) {X -= Right.X; Y -= Right.Y; Z -= Right.Z; return *this;}G_POINT operator-(const G_POINT<G_Float> &Right) const {G_POINT tmp = *this; return tmp-=Right;}I would be willing to bet you "goofed" again, and the operator- is failing for lack of a const.Second, it is common that ALL_CAPS_WITH_UNDERSCORES_MEANS_A_MACRO, and not a template....Next, it helps if you can post a minimium case of code that compiles and contains your problem.  What you posted is non-compiling code.;  It might also help if you explained your rational for having seperate point and vector classes.   ;Quote:Original post by DeyjaIt might also help if you explained your rational for having seperate point and vector classes.Naw, that makes perfect sense.  Points and vectors are different things.They both happen to be "vector fields" of the same dimension.But if you add two points together, you have a bug.  If you scale a point, you have a bug.  The vector "0" is special -- but the point "0" is not special.  If you use the point "0" you have a bug.  If you use the vector "0" you do not have a bug.A vector is a difference of points.By having the static type system distinguish between them, you can catch some bugs.  Sort of like rolling dimensional analysis into the static type system -- it helps sometimes.  :);  The problem was the overloaded operators not being const, due to an oversight in my hurried creation.  Pays to slow down I guess.I also chose to seperate points and vectors for that exact reason above.   ;  I have never yet seen a case where I didn't want to be able to apply the same set of functionality to a vector and a point.I DO what to scale points (grab the corner, multiple it by a scale factor, reset it) ... I DO want to add, difference, average two points (average of 2 points is there midpoint, difference of two points is the line segment which would connect them - and usefull for collision detection).I think you have fallen into the OO trap without realizing it.  You have made distinct objects out of concepts that are fundamentally one idea with multiple names.  The fundamental advancement of math and science is to unify all that may be unified - and nothing that may not.  So if the answer to the question "when would it not work to use an X instead of a Y" would be "never" then they should be one class.   ;  Furthermore, you need not duplicate code to differentiate. Make it a simple template with an integer template parameter, thentypedef vector_3<float, true> Vector3;typedef vector_3<float, false> Point3;Differentiating mathmatical types can have benifits - but this isn't one of those cases, because a point IS A vector.   