George
Fri Dec 14 02:23:01 PST 2007
Thanks cd,
Why,
> That returned instance of B is not an lvalue - it's a temporary rvalue.?
I think lvalue is something we can address and rvalue is something we can
not address. The reurn instance of B is a temporary object, I think an object
is addressable and should be lvalue?
Please feel free to correct me.
regards,
George
"Carl Daniel [VC++ MVP]" wrote:
> George wrote:
> > Hello everyone,
> >
> >
> > I am debugging MSDN code from,
> >
> >
http://msdn2.microsoft.com/en-us/library/0eestyah(VS.80).aspx
> >
> > here is my output,
> >
> > 1>main.cpp
> > 1>d:\visual studio 2008\projects\test_c4350\test_c4350\main.cpp(21) :
> > warning C4350: behavior change: 'B::B(A)' called instead of 'B::B(B
> > &)' 1> d:\visual studio
> > 2008\projects\test_c4350\test_c4350\main.cpp(13)
> >> see declaration of 'B::B'
> > 1> d:\visual studio
> > 2008\projects\test_c4350\test_c4350\main.cpp(9) : see declaration of
> > 'B::B' 1> A non-const reference may only be bound to an lvalue
> >
> > I do not quite understand why there is a warning A non-const
> > reference may only be bound to an lvalue and 'B::B(A)' called instead
> > of 'B::B(B &)'? Could anyone give some descriptions please?
>
> Class B has two constructors: B::B(B&) and B::B(A), and it also has a
> conversion operator B::operator A().
>
> In the example, an object of class 'B' named 'ap' is created and initialized
> with the results of a function call that returns an instance of 'B' by
> value.
>
> That returned instance of B is not an lvalue - it's a temporary rvalue.
>
> The warning is telling you that under VC++ 7.1 (and later), this results in
> this calling sequence:
>
> source()
> A::A() // create the return value for source
> B::B(A) // convert it from an A to a temporary B
> B::operator A() // convert that temporary B a temporary A
> B::B(A) // initialize ap with that temporary A
>
> .... while under VC7 (and before), the following sequence would have
> occurred:
>
> source()
> A::A()
> B::B(A)
> B::B(B&) // initialize ap with the temporary instance of B
>
> This change is required by the C++ standard which specifies that a non-const
> reference (such as the B& parameter in the B::B(B&) constructor) can only
> bind to an lvalue. Since the temporary B that's returned by source() is not
> an lvalue, this constructor cannot be used, so the compiler is forced to use
> the B::B(A) constructor, which it can use by virtue of B::operator A().
>
> Check out this forum thread, where Tom Widmer gave a good explanation of the
> rationale for this rule:
>
>
http://www.thescripts.com/forum/thread285370.html
>
> -cd
>
>
>