error: no match for 'operator='

Hi!

I've written a class called CEquation for mathematically handling polynomials.

I've overloaded the assignment operator because I need deep copying of dynamic memory.

CEquation eqn1, eqn2;

...
eqn1 = eqn2; // works fine
eqn1 = eqn2.Self(); // compilation error: no match for 'operator=' in 'eqn1 = CEquation::Self()()'

Where 'Self()' has been defined as:

CEquation CEquation::Self()
{
return *this;
}

Though it doesn't seem to be a problem, the declaration of the assignment operator is:

CEquation& CEquation::operator=(CEquation& eqn)
{
// do stuff
return *this;
}

I've never been so stumped on an error as I am now! Thank you for your help!
All the code below is correct at mine, so the problem is somewhere else, somewhat deeper...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class CEquation
{
public:
	CEquation Self();
	CEquation& CEquation::operator=(CEquation& eqn);
};


CEquation CEquation::Self()
{	return *this;  }


CEquation& CEquation::operator=(CEquation& eqn)
{	return *this; }

int main()
{
	CEquation eqn1, eqn2;

	eqn1 = eqn2; //works
	eqn1 = eqn2.Self(); //works
	return 0;
}
Last edited on
Self() returns an rvalue. Either change Self() to return a reference or change the parameter in operator= to const (depending on what you want to do) and it will work.
Thanks! That seems to have fixed the biggest problem, though unveiled another (I'll use another post, to keep the thread relevant)!
I agree with exception.

Because your self() returns a temporary copy of your eqn2 object that to be referenced by the =() operator in the same expression for assignment, which is not right.

Let me put it this way:
eqn1 = eqn2; // object to object copy, no temp
eqn1 = eqn2.Self(); // the Self() does not a reference, meaning, a temp object, but =() can not have reference to the temp object returned.

Obviously, your statement:
 
  CEquation& CEquation::operator=(CEquation& eqn)

is not a match for the given assignment expression.

Fix, either you do not reference to the incoming parameter in =() or you return a reference from the Self() as following:

 
  CEquation & CEquation::Self()   // returns a reference 


or

 
  CEquation& CEquation::operator=(CEquation  eqn)


But I would not go for the second one as the incoming parameter creates a temp object on the fly thus requiring an additional call to copy constructor.

When Self() returns a reference, then the object itself is returned, thus:
eqn1 = eqn2;
is exactly same as
equ1 = eqn2.Self();

Hope it is clearer now.

Good luck :)



> eqn1 = eqn2.Self(); // the Self() does not a reference, meaning, a temp object, but =() can not have reference to the temp object returned.

Why not? Rvalue can occur to the right of =. And temp object can too.
Look at the second post (mine one). The code is perfectly compiled.
@melkiy

No, most compilers complain referencing to a temp object. I just tried yours with with GCC++ compiler too. It complained same that there is no match.
Not sure what compiler you are using.

Though it could be supported by some compiler/implementations, I would not recommend the practice for portability reasons.

Check it out. Good luck :)


@satm2008

Still, please show me a reference to a temp object in the post #2 which may cause a compiler to complain.
@melkiy

what does the following method return? isn't it a temp object you think?

1
2
3
4
CEquation CEquation::Self()
{
return *this;
}



Hence the line
eqn1 = eqn2.Self();
returns an error stating
"Could not find a match for 'CEquation::operator =(CEquation)' in function main()"

because the declared is "CEquation::operator =(CEquation &)" expecting a reference to an accessible object.

The above compiler error returned by Borland 5.5 compiler.

Check it out.


[EDIT]
I just checked it with GNU (MingW) GCC++ compiler too. Same compliant.
error: no match for 'operator=' in 'eqn2 = CEquation::self()()'|

Good luck :)
Last edited on
Oh, i see.

I thought in the "return *this;" line of Self() method a copy constructor must be invoked. But in case operator= is defined and copy constructor is not defined explicitly within a class the former one seems to be envoked.

Still, if i do not overload neither operator=, nor copy constructor, the code is working, you may ensure yourself:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class CEquation
{
public:
	CEquation Self();
//	CEquation& CEquation::operator=(CEquation& eqn);
};


CEquation CEquation::Self()
{	return *this;  }


/*CEquation& CEquation::operator=(CEquation& eqn)
{	return *this; }*/

int main()
{
	CEquation eqn1, eqn2;

	eqn1 = eqn2; //works
	eqn1 = eqn2.Self(); //works
	return 0;
}

No, I dont think the operator=() would take place of copy constructor when an explicit copy constructor is not defined the class.
A copy constructor is provided by the compiler when one not defined explicitly in the class. So either one is invoked, but not =() as a replacement for that

In the case of
1
2
CEquation CEquation::Self()
{	return *this;  }


yes, it would invoke the copy constructor to copy the returned object to temp object. You can check yourself by writing a simple copy constructor with a simple cout statement to trace the copy constructor's call.

But if the Self() returns a reference then, as you know, it would not call any copy constructor. Because it is a reference and no temp to copy.

And to you note, if the explicit =() removed it works, yes obviously it would work as there is no explicit =() to receive the parameter by reference. It would obviously use a copy constructor provided by the compiler, which does bitwise copy.

Please note, when an explicit copy constructor and =() not provided in a class,
the assignment operator expression may call the compiler provided =() or copy constructor, it is implementation dependent. I guess, it calls copy constructor for the assignment too.


EDIT: Yes, it apparently is a wrong statement. As I realized later that an implicit default constructor, copy constructor, destructor and an assignment =() methods are provided by compiler hence the relevant method would be invoked when an explicit is not provided. Meaning, one would not be invoked for another. Implicit or explicit, its respective method would be called for copy constructor or =(), but not one for another.


Check it out. Good luck :)


Last edited on
The implicitly defined operator= has the signature
X& X::operator=(const X&)
It is defined if and only if all direct bases and non-static members have a copy assignment operator which take a const or const volatile reference or an object of that type.

it is implementation dependent

Though I don't exactly understand what you want to say, the definition of the implicitly-defined copy assignment operator (as well as copy constructor) is *not* implementation defined:

The implicitly-defined copy assignment operator for class X performs memberwise assignment of its subobjects. The direct base classes of X are assigned first, in the order of their declaration in the base-specifierlist, and then the immediate nonstatic data members of X are assigned, in the order in which they were declared in the class definition.
@exception

PS: I edited my last post above.

@melkiy
The program would work right if removed the explicit =() method, because, as noted above, the implicit =() method with const reference to incoming object would be invoked and worked good. The overloaded =() would not work as it is not referencing as const object.
As noted in our earlier posts, making a const reference to the incoming parameter would work, overloaded or implicit.

Good luck :)



Last edited on
Topic archived. No new replies allowed.