C++变量限定( 二 )


好像扯远了 , 其实我想说的是 , 在数据复制过程中 , 首先要分清是传值还是传引用!
如果是传值 , 好了 , 你是大爷 , 有钱人 , 想出错都难 。
因为新数据与源数据只是一次交易 , 后面就再也没关系了 , 源数据不会被改变 , 新数据的限定条件完全自己决定 。
从代码上看 , 如果等式左边是int a = ,那右边可以是任何代表int的变量 , 或者可以隐式转成int的变量 , 所有限定条件都不影响 , 且只要代码编译过 , 基本不会出错 。
28int a = 0;29int b = a;30int c = std::move(a);31 32int a2 = 0;33int &d = a2;34int e = d;35int f = std::move(d);36 37 38const int a3 = 0;39int g = a3;40int h = std::move(a3);
std::move()只有在
and cv- , 还有和的区别:
11int a = 2;12const int b = a;13volatile int c = a;14int &d = a;15const volatile int &e = a;16int &&f = std::move(a);
程序运行过程 , 就是不断复制数据的过程 , 在代码中 , 最常见的操作就是把一个值复制给另一个值 , 虽然对应到内存上 , 都是二进制的拷贝 , 但在编译器中 , 由于各种各样的原因 , 还保留着这组二进制值的某些特性 。那复制过程中 , 要不要保留这些特性呢?在没有类型推断之前 , 这个问题还比较简单 , 新的类型是要完全定义出来的 , 所以程序员必须要指定是否有某种限定(一般没有写 , 会有一个默认值 , 比如没有const那就是非const , 没有引用 , 那就是值 , 没有写右值那就是左值等等) 。但有了类型推导后 , 问题就复杂了 , 尤其是原值并不是默认值 , 而新值想用默认值的时候:
19int a = 1;20auto &b = a; //增加引用特性 , 可以21const auto &c = a; //增加const和引用 , 可以22 23const int d = 2;24auto e = 2; //e是否要保留const属性?不好决策 , 实际上是没有25e++;26auto &f = d; //f必须保留const属性27 //f++;28 29int g = 0;30int &h = g;31auto i = h;// i是否是g的引用 , 还是对应另一片内存?实际上对应另一片内存32i++;33cout << g << endl;35auto j = std::move(g);36 //int &&k = j; j是左值不是右值
从上面的例子可以看出 , auto作为类型推导时 , 不会保留 and cv- , 还有和 。
要想保留这些属性 , 必须要使用(auto)作为类型推导标识符:
19int a = 1;20auto &b = a; 21const auto &c = a; 22 23const int d = 2;24auto e = d; 25e++;26decltype(auto) e2 = d;27 //e2++; 编译失败 , 保留了const属性28auto &f = d; 29 //f++;30 31int g = 0;32int &h = g;33auto i = h;34i++;35cout << g << endl; //036decltype(auto) i2 = h;37i2++;38cout << g << endl; //1 保留了引用属性39