Historically, temporaries are rvalues, and rvalues aren't (and can't be)
cv-qualified. This rule worked well for non-class types, or for class
types with no member functions; since const-ness intervenes in function
overload resolution, the cv-qualification of a temporary must be
maintained. If a function returns simply X
, then the temporary is
not const, and you can call non-const functions on it; if the
functions returns X const
, then the temporary is const, and you can't
call non-const functions on it. As a general rule, it's probably
preferable to return class types as const
; i.e. X const f()
, rather
than X f()
. But there are definitely exceptions, and no body does it,
even in the cases where it would be more appropriate. And finally,
there are contexts where you can't specify the const-ness—function
style type conversions, for example—where the syntax doesn't
provide a means of specifying cv-qualifiers (except by using typedef's).
You might want to look at the output from the following code:
class C
{
std::string myComment;
public:
C( std::string const& comment ) : myComment( comment ) {}
void f()
{
std::cout << "Non const " << myComment << std::endl;
}
void f() const
{
std::cout << "Const " << myComment << std::endl;
}
};
typedef C const CC;
C
c()
{
return C("function return value");
}
C const
cc()
{
return C("function return value");
}
int
main()
{
C("function style conversion").f();
CC("function style conversion").f();
c().f();
cc().f();
}