#include <iostream>
using namespace std;
int main() {
/***************左值 和 右值****************/
//左值 和 右值 用等号(=)区分
//等号左边的为左值 --能对表达式取地址、或具名对象/变量。一般指表达式结束后依然存在的持久对象
//非匿名对象(包括变量),函数返回的引用,const对象等都是左值
//等号右边的为右值 --不能对表达式取地址,或匿名对象。一般指表达式结束就不再存在的临时对象
//函数返回的值等都是右值
/*
int a = 0; a左值 0右值
int b = 2; b左值 2右值
a = b + 1; a左值 b + 1右值
*/
//表达式不能做左值
// (a + b) = b + 1; 错误
// a++ = b + 1; 错误
// (a = 100) += b; 错误
//常量不能做左值
//100 = a + b; 错误
/*
const int a = 100;
const int& b = a; //可以绑定
int& b = a;// 错误int 和 const int 类型不一样(const限定符会被丢弃)
*/
/***************左值引用 和 右值引用****************/
//左值引用(就是别名) --绑定的值,能持久存在(能取到地址的值)
int& a;
//别名
int a = 10;
int &b = a;//b 就是 a 的别名(也就是说b是指向a的地址) --a是可以持久存在的
cout<<b<<endl;//10
//右值引用
//作用: 延续本来会被销毁的右值的生存期,
// 充分利用右值(特别是临时对象)的构造来减少对象构造和析构操作以达到提高效率
int&& b; //右值引用 --绑定的值,不能持久存在 (不能能取到地址的值)
//必须要绑定在右值(不能被改变的值)的引用上
int&& a1 = a * 100;//右值 -- a * 100不能持久存在
//左值不能绑在右值上面
int&& a2 = a; //错误
cout << "Hello JSRUN! \n\n - from C++ ." << endl;
return 0;
}