Article View: comp.std.c++
Article #3199Re: Explicit constructor call vs Temporaries
From: Matt Austern
Date: Thu, 01 Feb 1996 22:54
Date: Thu, 01 Feb 1996 22:54
72 lines
3095 bytes
3095 bytes
In article <4eq5p2$fpu@fsuj01.rz.uni-jena.de> mkt@isun04.inf.uni-jena.de (Tilo Koerbs) writes:
> About the error message in this posted code:
>
> > class T {
> > T();
> > ~T();
> > }
> >
> > class X {
> > X();
> > ~X();
> > f(T& t);
> > }
> >
> > int main() {
> > X x;
> > x.f(T()); // Compiler complained on this line
> > }
>
> The 'temporary' (it is an UNNAMED) T()-object is NOT const!
> Consider:
> class T {
> public:
> T();
> ~T();
> void nonConstFct() {}
> };
>
> int main() {
> T().nonConstFct(); // Allowed!!!
> }
>
> And so the compiler should have no problem with this code!
> I compiled it without any problem!
It's true that T().nonConstFct() is legal. It's also true that
x.f(T()) is illegal. Those two cases are very different!
The issue isn't whether what T() returns is const, but whether it's an
lvalue. This is a crucial point, since a non-const reference may not
be bound to an rvalue. Unfortunately, you have to read section 8.5.3
[dcl.init.ref] a little bit carefully to see this; it's quite
unambiguous, though. Paragraph 8 begins "--Otherwise [i.e. if a
reference is being initialized with an rvalue], the reference shall be
to a non-volatile const type (i.e., cv1 shall be const)."
(As usual, the complicated language in 8.5.3 simply formalizes what
you'd expect anyway. Creating a reference to a temporary is a
problematic operation, so it's forbidden except in certain restricted
cases.)
And, indeed, the explicit invocation of a constructor yields an
rvalue. The draft standard says this in several places, and implies
it in others. One such place is section 3.10 [basic.lval], paragraph
5: "Constructor invocations and calls to functions that do not return
references are always rvalues." See also the footnote to paragraph 2:
"Expressions such as invocations of constructors and of functions that
return a class type refer to objects, and the implementation can
invoke a member function upon such objects, but the expressions are
not lvalues."
--
Matt Austern
SGI: MTI Compilers Group
austern@isolde.mti.sgi.com
[ comp.std.c++ is moderated. Submission address: std-c++@ncar.ucar.edu.
Contact address: std-c++-request@ncar.ucar.edu. The moderation policy is
summarized in http://reality.sgi.com/employees/austern_mti/std-c++/policy.html
]
Technical Details
Message-ID:
<AUSTERN.96Feb1104027@isolde.mti.sgi.com>Path:
arc1-ca.pugleaf.net!engnews1.Eng.Sun.COM!taumet!clamageReferences:
<4e6plv$idn@eclipse.eng.sc.rolm.com> <4eq5p2$fpu@fsuj01.rz.uni-jena.de>Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!engnews1.Eng.Sun.COM!taumet!clamage From: austern@isolde.mti.sgi.com (Matt Austern) Newsgroups: comp.std.c++ Subject: Re: Explicit constructor call vs Temporaries Date: 1 Feb 1996 22:54:42 GMT Organization: SGI Approved: clamage@eng.sun.com (comp.std.c++) Message-ID: <AUSTERN.96Feb1104027@isolde.mti.sgi.com> References: <4e6plv$idn@eclipse.eng.sc.rolm.com> <4eq5p2$fpu@fsuj01.rz.uni-jena.de> Reply-To: austern@cardboard.mti.sgi.com NNTP-Posting-Host: taumet.eng.sun.com Content-Type: text X-Nntp-Posting-Host: isolde.mti.sgi.com In-Reply-To: mkt@isun04.inf.uni-jena.de's message of 01 Feb 1996 09:54:08 PST Content-Length: 2096 X-Lines: 67 Originator: clamage@taumet