Overloading Errors In Templated Classes

Started by
5 comments, last by rip-off 14 years, 1 month ago
I have a simple 2D vector class and I want to add some overloading like so, but it gives me errors.
//! @file CVector2D.h

#ifndef _JE3D_CVECTOR2D_H_
#define _JE3D_CVECTOR2D_H_

#include "IShared.h"
#include "IObjectStub.h"

namespace JE3D
{
	//! The 2D vector class.
	template <class T>
	class CVector2D
		: public virtual IObjectStub
	{
		public:
			//! The 2D vector constructer.
			CVector2D(T xPos, T yPos)
				: x(xPos), y(yPos)
			{
			}
			
			//! Sets the X value.
			void setX(T newX)
			{
				x = newX;
			}
			
			//! Sets the Y value.
			void setY(T newY)
			{
				y = newY;
			}
			
			//! Returns the X value.
			T getX(void)
			{
				return x;
			}
			
			//! Returns the Y value.
			T getY(void)
			{
				return y;
			}
			
			//! Compares two vectors to see if they're the same.
			CVector2D<T> operator ==(const CVector2D &vectorOther)
			{
				return (x == vectorOther.getX() && y == vectorOther.getY());
			}
			
			//! Compares two vectors to see if they aren't the same.
			CVector2D<T> operator !=(const CVector2D &vectorOther)
			{
				return (x != vectorOther.getX() || y != vectorOther.getY());
			}
			
			//! Adds two vectors together.
			CVector2D<T> operator +(const CVector2D &vectorOther)
			{
				x += vectorOther.getX();
				y += vectorOther.getY();
				
				return this;
			}
			
			//! Subtracts two vectors from eachother.
			CVector2D<T> operator -(const CVector2D &vectorOther)
			{
				x -= vectorOther.getX();
				y -= vectorOther.getY();
				
				return this;
			}
		
		private:
			T x; ///< The X value.
			T y; ///< The Y value.
	};
	
	typedef CVector2D<s8> CVector2DS8; ///< A 2D vector using s8s.
	typedef CVector2D<u8> CVector2DU8; ///< A 2D vector using u8s.
	typedef CVector2D<s16> CVector2DS16; ///< A 2D vector using s16s.
	typedef CVector2D<u16> CVector2DU16; ///< A 2D vector using u16s.
	typedef CVector2D<s32> CVector2DS32; ///< A 2D vector using s32s.
	typedef CVector2D<u32> CVector2DU32; ///< A 2D vector using u32s.
	
	typedef CVector2D<f32> CVector2DF32; ///< A 2D vector using f32s.
}

#endif
Quote:In member function `JE3D::CVector2D<T> JE3D::CVector2D<T>::operator+(const JE3D::CVector2D<T>&) [with T = JE3D::u16]':| E:\Projects\C++\DIS\code\source\COptionsState.cpp|137|instantiated from here| error: passing `const JE3D::CVector2D<JE3D::u16>' as `this' argument of `T JE3D::CVector2D<T>::getX() [with T = JE3D::u16]' discards qualifiers| error: passing `const JE3D::CVector2D<JE3D::u16>' as `this' argument of `T JE3D::CVector2D<T>::getY() [with T = JE3D::u16]' discards qualifiers| error: conversion from `JE3D::CVector2D<JE3D::u16>* const' to non-scalar type `JE3D::CVector2D<JE3D::u16>' requested|
Advertisement
Looking at it briefly, it looks like you're trying to call a non-const method on a const parameter in your overloaded operators.

Try changing
T getX(void)
...
to
T getX(void) const
...
and so on for the other getters.

[size="1"]Try GardenMind by Inspirado Games !
All feedback welcome.
[s]
[/s]

[size="1"]Twitter: [twitter]Owen_Inspirado[/twitter]
Facebook: Owen Wiggins

[size="1"]Google+: Owen Wiggins

Thanks.
I know this isn't why you posted, but it looks to me like your + and - operators are mutating, which they shouldn't be. In other words, a statement such as the following:
v3 = v1 + v2;
Shouldn't modify v1 or v2, but with your implementation, v1 will be modified.

Also, in general, binary operators such as == and binary + and - should (arguably) be implemented as non-member functions rather than as member functions. (This, along with various other relevant issues, is discussed in quite a few previous threads on implementing a vector class.)

I see a couple of other stylistic and technical issues, but I realize you didn't ask for general feedback, so I'll stop there (I thought the +/- thing was worth mentioning though, as it's definitely something you'll want to fix).
Aargh. Read error messages.

When you see "discards qualifiers" at the end of an error message, your error has something to do with const correctness. It has nothing to do with the templating here. IMX getting the template logic wrong is seldom the cause of the error, although having it around at all usually makes the error messages longer. :)

So. Const correctness. You go back and look at the beginning of the error message. You see "passing", which means the problem is with calling a function, rather than making an assignment or returning a value. You skip the type and see "as 'this' argument", and now you know it's talking about a member function, and furthermore, that the problem is that you're trying to call the function on a const object, and that this "discards qualifiers".

What does that mean? 'const' is a qualifier. If you discard that qualifier, you're forgetting that something is const when it is. In your case, that's the object you're calling the member function upon.

So, the solution is to remember that the object is const when you call the function. You do that by having the function declare that it does not modify the this-object. The syntax for that has been shown to you.

Anyway. What the hell is an "IObjectStub", and why does "a simple 2D vector class" need to inherit from it?! Why on earth would you ever want to use a 2D vector polymorphically? What does a 2D vector have in common with other things that makes for a useful interface?
Quote:Original post by Zahlman
Anyway. What the hell is an "IObjectStub", and why does "a simple 2D vector class" need to inherit from it?! Why on earth would you ever want to use a 2D vector polymorphically? What does a 2D vector have in common with other things that makes for a useful interface?


Moreover, it's using virtual inheritance. To put it bluntly, baby Jesus is crying right now.
Are you even going to use all those template types? A vec2 composed of floats works for most games. Keep in mind the YAGNI principle.

Using operator== and operator != to compare floats is a bad idea, floating point accuracy will bite you.

This topic is closed to new replies.

Advertisement