Q
Q
Qubc2021-08-14 18:43:31
C++ / C#
Qubc, 2021-08-14 18:43:31

Why can a non-const method be called on a temporary object?

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());
}


The compiler creates a temporary object after calling f5, temporary objects have a const qualifier. Why the compiler does not swear? The method can change the static variable. Is this some kind of optimization or habit that everyone is used to?

Answer the question

In order to leave comments, you need to log in

2 answer(s)
W
Wataru, 2021-08-16
@Qubc

Regarding the call of non-constant methods - why did you get the idea that they should not be possible? Temporary objects do not have const qualifiers. Otherwise it would be impossible to do things like SomethingBuilder().WithA().WithB().Finalize().

//! f6() = X(1);

The assignment operator requires an Lvalue on the left. A temporary object is an Rvalue. It can only be placed to the right of =. And not because it has a const qualifier.
This is most likely because, well, there's no point in overwriting a temporary object. It is temporary and cannot be accessed later.
//! f6().modify();

Here is an attempt to call a non-constant method on a const (and temporary - but it doesn't matter) object.
//! f7(f5());

Apparently, this is to exclude a certain class of errors. If you pass something as a non-constant reference, then it must change inside and outside these changes must be visible. Otherwise, it would be possible to pass by constant reference or by value. But you pass a temporary object there - it will not be visible from the outside. It exists only in this line. Therefore, in C++, you cannot initialize non-const lvalue references through rvalue (temporary objects).

J
jcmvbkbc, 2021-08-15
@jcmvbkbc

// Causes compile-time errors:
//! f7(f5());

Look, you can also do this:
class X {
 int i;
public:
 X(int ii = 0);
 void modify();
 X& ref() {return *this;}
};
...
f7(f5().ref());

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question