Hi,
I have a bit of a problem that looks as fallows:
class cls {
public:
cls () {}
// the problem is here
// cls (cls& ) {}
const cls func (cls& ) {
return cls();
}
};
int main() {}
In the code above, if I remove the coment from the copy constructor, the code won't compile with the error: no matching function for call to `cls::cls(cls)'.
But the program compiles just fine in this form.
Does anyone know why the compiler behaves this way?
Thanks in advance.
To answer your question as to why the compiler does this:
return cls(); creates a temporary unnamed object and returns it. Since the function returns an object by value, a copy of the temporary object is created.
The copy is created by calling the copy ctor (obviously).
The problem is, temporary objects are const. So this unnamed temporary object is const, and therefore it can't call that ill-formed copy ctor because the compiler can't cast a const cls& to a non-const cls&.
Thanks for your answer.
There are still some things I don't understand.
Bruce Eckel says in his book "thinking in C++" page 534, in the paragraph "the return optimization" that (I quote):
"When the compiler sees you do this, it knows that you
have no other need for the object it’s creating than to return it. The
compiler takes advantage of this by building the object directly into
the location of the outside return value. This requires only a single
ordinary constructor call (no copy-constructor is necessary) "
And I think it doesn't make sense to create 2 temporaries as you say.
C++ syntax and the resulting compiled code are 2 different things.
In the above C++ syntax you're creating a temporary object and then copying it. Therefore the copy must be legal in order for it to compile.
On the other hand, the compiler is free to optimize away unnecessary copies. So the final program might not copy the object at all. But even if that's the case, the code is still implying that an object is being copied, and therefore the copy must be legal.