------------------------------不符合规则1,被规则2处理-----------------------------------------
extern B f();
const A& rca2 = f();// f()返回值是一个类类型的rvalue,
// the cv1 >= cv2: const > 没有修饰符,2.1能够处理
struct X {
operator B();
operator int&();
} x;
const A& r = x;// x 是类类型的
// r 与x 不是reference-compatible的
// x 通过operator B()返回一个类类型的prvalue, tmpB
// r 与tmpB 的关系满足2.1的条件,2.2能够处理
-----------------------不符合规则1,也不符合规则2,被规则3处理---------------------------
const double& rcd2 = 2; // 2,不是一个lvalue/xvalue/类类型的prvalue/函数返回的左值,等。
// 创建一个临时变量2.0,3能够处理
--------不符合规则1,也不符合规则2,也不符合规则3,被规则4处理----------------------
double d2 = 1.0;
double&& rrd2 = d2; // rrd2是一个rvalue reference,不能使用lvalue 赋值。4能够处理
-----------------------------------------其他一些例子-------------------------------------------------------------
const volatile int cvi = 1;
const int& r2 = cvi; // error, in this example, the cv1 <= cv2, which violate the 1.1
*************************回到我们的例子*************************
class Dog
{
public:
Dog(){}
virtual ~Dog(){}
};
void NonConstReference (Dog & dog )
{
//tell the dog to do something here
}
void TestNonConstReference ()
{
NonConstReference( Dog());
}
NonConstReference( Dog())调用,在栈上创建了一个类类型的prvalue。
根据ISO文档,它不能规则1接纳,就只能由规则2继续处理。
规则2要求NonConstReference(Dog & dog )中的Dog & dog 必须是const Dog & dog。
而这里显然不是,所以抱错。
************************编译器为我们作了什么?语义分析*****************************
编译器,在严格的按照,c++语言的设计来执行语义检查:
目标是一个lvalue reference, 那么就不能给我一个rvalue.
要么就把目标设置成const lvalue reference.
如果一个参数是以非const引用传入,c++编译器就认为程序在函数中修改这个值,并且想要这个被修改过的值。
但如果你把一个临时变量当作非const引用参数传进来,程序并没有机会继续访问这样的变量,从而使修改一个临时变量变得毫无意义的。
从而c++编译器加入了临时变量不能作为非const引用的这个语义限制,意在限制这个非常规用法的潜在错误。