class Date {
public:
Date(string &s) :date(s) {}
string date;
};
void printDate(Date &date);
int main()
{
printDate(string("1989/06/04"));//提示非常量引用的初始值必须为左值
return 0;
}
void printDate(Date &date)
{
}
出现提示之后就开始捋思路
首先类隐式转换的过程
1、代码执行了接受string类型的Date类构造函数
2、通过构造函数创建了一个临时的Date对象,随后将对象作为初始值来初始化printDate的Date对象引用
根据提示信息,错误明显发生在第二步,所以问题转变为非常量引用的初始化,根据提示临时的Date对象不是左值,网上搜了一下,发现确实临时对象具有不可更改的属性,也就是自带顶层const,问题出在printDate的形参类型上,改为const Date &date解决。
又回顾了C++ Primer关于对const引用的描述,答案更加清晰了:
举例:
double dval = 3.14;
const int &ri = dval;
此处ri引用了一个int型的数,但dval是一个双精度浮点数,因此为了确保ri绑定一个整数,编译器把上述代码转换如下:
const int temp = dval;//隐式类型转换,同类隐式转换一个道理
const int &ri = temp;
监视&ri和&dval发现确实是两个不同的地址,其中&ri存储的是整数3,&dval存储的浮点数,所以说确实生成了临时量。
假设ri不是常量引用,就允许通过ri改变dval的值,但是由于隐式类型转换的存在,修改ri的值仅仅影响临时量的值,不能影响dval的值,所以用非常量引用 引用 其他类型(可转换)的对象没有意义,C++语言将这种行为归为非法。
回到最开始的问题上,也就是说:
string s = "hello,world!";
Date &date = s;//非法,需要加上顶层const
const Date &date = s;//正确
至此问题解决。