"no match for 'operator='", even if it is there

Dear all,
I have a strange problem that I don't figure out.
myclass is the following:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
class myclass{
public:
	myclass();
	~myclass();
	double & operator[](unsigned int);
	myclass & operator=(myclass &);
	myclass operator+(myclass &);
private:
	double fPrivate[3];
};

myclass::myclass(){
	for(unsigned int ii = 0; ii < 3; ii++){
		fPrivate[ii] = 0.;
	}
}

myclass::~myclass(){
}

double & myclass::operator[](unsigned int ii){
	if(ii < 3) return fPrivate[ii];
}

myclass & myclass::operator=(myclass & right){
	for(unsigned int ii = 0; ii < 3; ii++){
		fPrivate[ii] = right[ii];
	}
	return *this;
}

myclass myclass::operator+(myclass & right){
	myclass result;
	for(unsigned int ii = 0; ii < 3; ii++){
		result[ii] = fPrivate[ii] + right[ii];
	}
	return *this;
}

and this is the main:
1
2
3
4
5
6
int main(){
	myclass a, b;
	myclass c = a + b;
	cout << c[1] << endl;
	return 0;
}

This compiles and runs without problems.
When I change the main into
1
2
3
4
5
6
7
int main(){
	myclass a, b;
	myclass c;
	c = a + b;
	cout << c[1] << endl;
	return 0;
}

I get the following error message

error: no match for 'operator=' in 'c = myclass::operator+(myclass&)(((myclass&)(& b)))'

Isn't this strange?
What is the difference between the two main codes?
I don't get the error message.
Thanks in advance.

Fil
operator= needs to take the argument either by value or by reference to const.

The following works for me:

1
2
3
4
myclass & myclass::operator=(myclass right) {
    std::swap(fPrivate, right.fPrivate);
    return *this;
}


Oh, and yes, the difference is that the second code attempts assignment, while the first does not (the equals sign doesn't always mean assignment, just like the asterisk doesn't always mean multiplication)
Last edited on
First of all executing of expression a + b results in creating unnamed temporary object. Temporary objects can be binded only with const reference (if of course you are not using the language extensions of MS VC++) .
In the code snip below

1
2
3
4
5
6
int main(){
	myclass a, b;
	myclass c = a + b;
	cout << c[1] << endl;
	return 0;
}


in the statement

myclass c = a + b;

object c is being created. So in this case a copy constructor is used. You did not define a copy constructor yourself so the compiler created implicit copy constructor of type

myclass( const myclass & );

Because this implicit copy constructor has const reference as the parameter it can accept a temporary unnamed object.

Now consider the second code snip

1
2
3
4
5
6
7
int main(){
	myclass a, b;
	myclass c;
	c = a + b;
	cout << c[1] << endl;
	return 0;
}


Here object c was created in statement

myclass c;

by using the default constructor. So in statement

c = a + b;

the copy assignment operator will be used instead of the copy constructor. You defined it such a way that it takes non-const reference to an object of the class. But non-const reference can not be binded with a temporary unnamed object. So the compiler issues the error.

Though your copy assignment operator is correct it is better to define it with const reference as the parameter. In this case you can use it with temporary unnamed objects or const objects in the right side of the assignment operator.
Last edited on
Crystal clear, thanks to all!
Just in case you are running into another missbehavior soon: probably you want to return result rather than *this from +
zombie, thanks.
copy paste problem
Topic archived. No new replies allowed.