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
> 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
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
> 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