Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

A non-const reference may only be bound to an lvalue?

16 views
Skip to first unread message

George2

unread,
Dec 14, 2007, 1:17:23 AM12/14/07
to
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?


thanks in advance,
George

Tomás Ó hÉilidhe

unread,
Dec 14, 2007, 4:38:59 AM12/14/07
to
George2 <george4...@yahoo.com> wrote in comp.lang.c++:

> I do not quite understand why there is a warning A non-const reference

> may only be bound to an lvalue?


A const reference can be bound to:
R-value
L-value

A non-const reference can be bound to:
L-value

This means that you can do this:

int const &x = 5;

But you _can't_ do this:

int &x = 5;

, thus preventing you from trying to modify a literal, or any kind of R-
value for that matter.

I realise you can have a non-const R-value, (such as if a function call
were to return a non-const class object), but I don't think it it'd be a
good idea to have non-const references to R-values floating around,
especially if these non-const references didn't "extend the lifetime" of
the R-value (which is likely to be a temporary a lot of the time).

The way I like to understand binding a const reference to an R-value is
that the following two are identical:

ClassType const &x = FunctionReturnsObject();

and:

ClassType const ret = FunctionReturnsObject();

ClassType const &x = ret;

, thus it's easy to see how the "lifetime is extended".

I think many people have suggested tho that C++ _should_ allow the
following:

void Func(ClassType &x);

ClassType FunctionReturnsObject(void);

int main(void)
{
Func(FunctionReturnsObject());
}

--
Tomás Ó hÉilidhe

iftekhar

unread,
Dec 14, 2007, 4:47:25 AM12/14/07
to
Hi George,

The function "B source() { return A(); }" create a temporary of type
B, and a a temporary is a rvalue.
according to the C++ standard a rvalue cannot be bound to a non-const
reference, i.e. B(B&){} cannot be called since it take a non-const
reference. Instead, the temporary B is converted to A again using
"operator A()" and passed to the B(A){}.

Hope it helps,

Iftekhar


// C4350.cpp
// compile with: /W1
#pragma warning (default : 4350)
class A {};

class B
{
public:
B(B&){}
// try the following instead
// B(const B&){}

B(A){}
operator A(){ return A();}
};

B source() { return A(); }

int main()
{
B ap(source()); // C4350

James Kanze

unread,
Dec 14, 2007, 7:44:03 AM12/14/07
to
On Dec 14, 7:17 am, George2 <george4acade...@yahoo.com> wrote:

> I am debugging MSDN code from,

> http://msdn2.microsoft.com/en-us/library/0eestyah(VS.80).aspx

Note that the example is designed expressedly to provoke this
error.

> 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
> &)'?

What don't you understand about it? What is provoking it? Or
why it is an error? (It's forbidden by the C++ standard. The
rule was introduced some time around 1990, or a little before,
because practical experience showed too many errors resulting
from an implicit conversion binding to a non-const reference.)

At the beginning, many compilers only generated a warning, to
give people time to modify their code, but today, practically
all compilers treat it as an error. (Except Microsoft, I
think.)

> Could anyone give some descriptions please?

Of what? The rule. The rationale behind it? Or is there some
term or expression in it that you don't understand.

--
James Kanze (GABI Software) email:james...@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

0 new messages