In Eckel, Vol 1, pg:367
//: C08:ConstReturnValues.cpp
// Constant return by value
// Result cannot be used as an lvalue
class X {
int i;
public:
X(int ii = 0);
void modify();
};
X::X(int ii) { i = ii; }
void X::modify() { i++; }
X f5() {
return X();
}
const X f6() {
return X();
}
void f7(X& x) { // Pass by non-const reference
x.modify();
}
int main() {
f5() = X(1); // OK -- non-const return value
f5().modify(); // OK
// Causes compile-time errors:
//! f7(f5());
//! f6() = X(1);
//! f6().modify();
//! f7(f6());
} ///:~
Why does f5() = X(1) succed? What is going on here???
Q1. When he does X(1) – what is going on here? Is this a constructor call –
shouldn’t this then read X::X(1); Is it class instantiation – isn’t class
instantiation something like: X a(1); How does the compiler determine what
X(1) is?? I mean.. name decoration takes place so.. X(1) the constructor
call would translate to something like: globalScope_X_int as the function
name.. ???
Q2. Surely a temporary object is used to store the resulting object that X(1)
creates and then would’t that be then assigned to the object f5() returns
(which would also be a temporary object)? Given that f5() returns a temporary
object that will be soon be discarded, how can he assign one constant temporary
to another constant temporary??? Could someone explain clearly why:
f7(f5()); should reult in a constant temporary and not plain old f5();
I wasn’t entirely satisfied by the answers, so I took a look at:
. Regarding Bruce Eckel’s coverage of “Temporaries”,
well, as I suspect and as Christian Rau directly points out, it’s plain
wrong! Grrr! He’s (Eckel’s) using us as guinea pigs!! (it would be a
good book for newbies like me once he corrects all his mistakes)
The other part of the answer is found in: “Meyer: Effective C++”, in
the “Introduction”:
Regarding my questions:
Here a new object isn’t being initialized, ergo this is not
initialization(copy constructor): it’s an assignment (as
Matthieu M pointed out).
The temporaries are created because as per Meyer (top paragraphs),
both functions return values, so temporary objects are being created.
As Matthieu pointed out using pseudo-code, it becomes:
__0.operator=(__1)and a bitwise copy takes place(done by thecompiler).
Regarding:
ergo, a temporary cannot be created (Meyer: top paragraphs).
If it had been declared:
void f7(const X& x);then a temporary wouldhave been created.
Regarding a temporary object being a constant:
Meyer says it (and Matthieu): “a temporary will be created to bind to that
parameter.”
So a temporary is only bound to a constant reference and is itself not
a “const” object.
Regarding:
what is
X(1)?Meyer, Item27, Effective C++ – 3e, he says:
So
X(1)is a function-style cast.1the expression is being cast totype
X.And Meyer says it again: