左值表达式上的一些标准转换;而对于需要右值的场合,一个左值表达式往往需要经过函数-指针转换、数组-指针转换和左右值转换等。
Ex2.8
char c[100];
char (&rarr)[100]=c; // suppresses array-to-pointer conversion on c.
char* p1=c; //c will be adjusted to type "char *".
void f();
void (&rf)()=f; //suppresses function-to-pointer conversion on expression f
void (*pf)()=f; //f will be adjusted to type "pointer to function
//type void () ".
sizeof(0, c); // the expression''s value is sizeof(char*) in c;
//100 in C++, since the expression (0,c) is an lvalue
//in C++.
2.8.2 除此之外,有些场合无论左右值都可接受,但是根据表达式的左右值性,执行不同的行为:
Ex2.9
typeid''s behavior
class B{ public: virtual f() { } }; //polymorphic type.
class A {};
B& foo();
typeid(foo()); // foo() is an lvalue of a polymorphic type. Runtime check.
typeid(A()); //rvalue, statically
typeid(B()); //rvalue, statically
A a;
typeid(a); //lvalue of a non-polymorphic type, statically.
//..........................
reference''s behavior
class C{ private: C(const C&); };//NOTICE
extern C c;
C g();
C& rc1=c; //bind directly. (1)
C& rc2=g()//error. (2)
const C& r2=g(); //error. (3)
这里表达式c是个左值表达式,且其类型(C)与rc1的类型兼容,因此(1)式直接绑定;而(2)和(3)中,右边的表达式均为右值表达式,且该右值表达式又不能通过user conversion转换成与左边的变量兼容的类型,因此语义上这里需要构造一个临时对象,并使用C的构造函数和右值g()来初始化它,但是这里的C的拷贝构造函数(copy ctor)又不可访问,因此以上声明语句非法。 |