Doubt with overloading operators in C++

Started by
8 comments, last by Tsumuji 17 years, 5 months ago
I'm playing here with overloading operators, but get a strange error in a assigment:

#include <iostream>

class vec2{
	float value[2];
	public:
		vec2(){
			value[0] = 0.3;
			value[1] = 0.3;
		}
		vec2(float p1, float p2){
			value[0] = p1;
			value[1] = p2;
		}
		vec2& operator= ( const vec2& vp ){
			value[0] = vp[0];
			value[1] = vp[1];
			return *this;
		}
		float& operator[] ( int idx ){
			return value[idx];
		}
};

int main(){
	vec2 VEC;
	VEC = vec2(2.0, 3.4);
	std::cout << VEC[0] << std::endl;
	std::cout << sizeof(VEC) << std::endl;
	return 0;
}


Get "$ g++ vec.cpp -o vec -Wall vec.cpp: In member function `vec2& vec2::operator=(const vec2*)': vec.cpp:15: error: cannot convert `const vec2' to `float' in assignment " from compiler. What I'm doing wrong here?
Advertisement
The compiler expects vp to be a pointer, as seen in the error message:
vec.cpp: In member function `vec2& vec2::operator=(const vec2*)'


Change your function definition to using a reference and it will work fine.
just curios as to why you would return a reference of the parameter;
ooops, wrong error message. This is the correct:

$ g++ vec.cpp -o vec -Wall
vec.cpp: In member function `vec2& vec2::operator=(const vec2&)':
vec.cpp:15: error: passing `const vec2' as `this' argument of `float& vec2::operator[](int)' discards qualifiers
vec.cpp:16: error: passing `const vec2' as `this' argument of `float& vec2::operator[](int)' discards qualifiers
Your problem here is a const-correctness issue.
vec2& operator= ( const vec2& vp ){	value[0] = vp[0];	value[1] = vp[1];	return *this;}float& operator[] ( int idx ){	return value[idx];}


The parameter to operator= has type const vec2&. This means you can only perform const operations in the body of the function. operator[], however, is not const. You should really not make it const because it returns a reference. Instead, you should set the value yourself like so:
vec2& operator= ( const vec2& vp ){	value[0] = vp.value[0];	value[1] = vp.value[1];	return *this;}


HTH
oh yeah, I forgeted that I can access the value directly. So wich is the best way to implement? (the fastest)

vec2& operator= ( const vec2& vp ){
value[0] = vp.value[0];
value[1] = vp.value[1];
return *this;
}
float& operator[] ( int idx ){
return value[idx];
}

or

vec2& operator= ( const vec2& vp ){
value[0] = vp[0];
value[1] = vp1];
return *this;
}
float operator[] ( int idx ) const{
return value[idx];
}


I think is equal. or no?
Both will work, but the second one does not allow operator[] to be treated as an l-value. For example, the following code will not work:
vec2 a;
a[0] = 2.3;

With the first method, this will work because you return a reference to the value. So, assuming you want to be able to update your vec2's after they're created, I'd go with method 1 [smile].
You'll want to write *both* const and non-const versions of the operator[], lest you lose desired functionality. Overload resolution will sort things out and call the right one depending on context.
Sharlin has the right idea.

To spoon-feed it:

// Yes, we do want both of these!float& vec2::operator[] ( int idx ){	return value[idx];}const float& vec2::operator[] ( int idx ) const {// Or just return 'float', but I prefer this for symmetry	return value[idx];}
ok guys, thanks for the answers.
So I implemented in that way:
typedef class vec2{	GLfloat value[2];	public:		//GLfloat x;		//GLfloat y;				vec2( );		vec2( GLfloat );		vec2( GLfloat, GLfloat );		vec2& operator= ( const vec2& );		GLfloat& operator[] ( int );		const GLfloat operator[] ( int ) const;		vec2& operator+ ( const vec2& );		vec2& operator- ( const vec2& );		vec2& operator* ( const vec2& );		vec2& operator/ ( const vec2& );		float* raw();};vec2::vec2( ){	this->value[0] = 0.0; this->value[1] = 0.0;}vec2::vec2( GLfloat fp ){	this->value[0] = fp; this->value[1] = fp;}vec2::vec2( GLfloat fp1, GLfloat fp2 ){	this->value[0] = fp1; this->value[1] = fp2;}vec2& vec2::operator= (  const vec2& vp ){	this->value[0] = vp.value[0];	this->value[1] = vp.value[1];	return *this;}GLfloat& vec2::operator[] ( int ip ){	return this->value[ip];}const GLfloat vec2::operator[] ( int ip ) const{	return this->value[ip];}vec2& vec2::operator+ (  const vec2& vp ){	this->value[0] += vp.value[0];	this->value[1] += vp.value[1];	return *this;}vec2& vec2::operator- (  const vec2& vp ){	this->value[0] -= vp.value[0];	this->value[1] -= vp.value[1];	return *this;}vec2& vec2::operator* (  const vec2& vp ){	this->value[0] *= vp.value[0];	this->value[1] *= vp.value[1];	return *this;}vec2& vec2::operator/ (  const vec2& vp ){	this->value[0] /= vp.value[0];	this->value[1] /= vp.value[1];	return *this;}float* vec2::raw( ){	return this->value;}

This topic is closed to new replies.

Advertisement