场景:

  1. 在 remove_reference 结构体中能看到右值引用的身影 &&, 那么这里的右值引用究竟有什么用呢?

  2. 常常也发现int& 和int&& 这两种相似的应用类型,第一种是左值引用声明,另外一种是右值引用声明.
  3. 下面的样例直接參考的 cppreference,已经写的非常完整了,不是必需又一次写.

參考:

1.Reference declaration

2.Rvalue Reference Declarator: &&

3.Lvalue Reference Declarator: &

语法

左值引用声明: & attr(optional) declarator (1)

右值引用声明: && attr(optional) declarator (2) (since C++11)

左值引用声明 &

–1. 左值引用能够理解为对象的别名, 左值引用必须被初始化并且不能被又一次赋值.

#include <iostream>
#include <string> int main()
{
std::string s = "Ex";
std::string& r1 = s;
const std::string& r2 = s; r1 += "ample"; // modifies s
// r2 += "!"; // error: cannot modify through reference to const
std::cout << r2 << '\n'; // prints s, which now holds "Example"
}

–2. 在调用函数时,能够被用来作为引用參数.

#include <iostream>
#include <string> void double_string(std::string& s)
{
s += s; // 's' is the same object as main()'s 'str'
} int main()
{
std::string str = "Test";
double_string(str);
std::cout << str << '\n';
}

–3. 当一个函数的返回值是左值时, 这个函数的调用的表达式能够被觉得是一个左值表达式.


#include <iostream>
#include <string> char& char_number(std::string& s, std::size_t n)
{
return s.at(n); // string::at() returns a reference to char
} int main()
{
std::string str = "Test";
char_number(str, 1) = 'a'; // the function call is lvalue, can be assigned to
std::cout << str << '\n';
}

右值引用声明 &&

–1. 右值引用声明能够差别一个左值和右值.

–2. 右值引用直至Move语义的实现, 它能够把暂时对象(一般不能引用)的资源移动到其它地方去.

–3. 右值引用也能够用来扩展暂时对象的生命周期,

#include <iostream>
#include <string> int main()
{
std::string s1 = "Test";
// std::string&& r1 = s1; // error: can't bind to lvalue const std::string& r2 = s1 + s1; // okay: lvalue reference to const extends lifetime
// r2 += "Test"; // error: can't modify through reference to const std::string&& r3 = s1 + s1; // okay: rvalue reference extends lifetime
r3 += "Test"; // okay: can modify through reference to non-const
std::cout << r3 << '\n';
}

–4. 假设函数有左值和右值引用的重载,调用时会匹配调用, 传左值调用左值重载, 右值调用右值重载. 这样就能够支持Move Constructor 和 Move Assignment 的实现.

#include <iostream>
#include <utility> void f(int& x)
{
std::cout << "lvalue reference overload f(" << x << ")\n";
} void f(const int& x)
{
std::cout << "lvalue reference to const overload f(" << x << ")\n";
} void f(int&& x)
{
std::cout << "rvalue reference overload f(" << x << ")\n";
} int main()
{
int i = 1;
const int ci = 2;
f(i); // calls f(int&)
f(ci); // calls f(const int&)
f(3); // calls f(int&&)
// would call f(const int&) if f(int&&) overload wasn't provided
f(std::move(i)); // calls f(int&&)
}

[C++11]_[0基础]_[左值引用声明和右值引用声明]的更多相关文章

  1. [Zlib]_[0基础]_[使用zlib库压缩文件]

    场景: 1. WIndows上没找到系统提供的win32 api来生成zip压缩文件, 有知道的大牛麻烦留个言. 2. zlib比較经常使用,编译也方便,使用它来做压缩吧. MacOSX平台默认支持z ...

  2. [C/C++11语法]_[0基础]_[lamba 表达式介绍]

    场景 lambda 表达式在非常多语言里都有一席之地,由于它的原因,能够在函数里高速定义一个便携的函数,或者在函数參数里直接高速构造和传递. 它能够说是匿名函数对象,一般仅仅适用于某个函数内,仅仅做暂 ...

  3. [libcurl]_[0基础]_[使用libcurl下载大文件]

    场景: 1. 在Windows编程时, 下载http页面(html,xml)能够使用winhttp库,可是并非非常下载文件,由于会失败. 由此引出了WinINet库,无奈这个库的稳定性比較低,使用样例 ...

  4. [wxWidgets]_[0基础]_[经常更新进度条程序]

    场景: 1. 非常根据程序的进展需要处理业务,以更新进度条,进度条的目的是为了让用户知道业务流程的进度.一个进度条程序更友好,让用户知道在程序执行.不是没有反应. 2. 现在更新见过这两种方法的进展. ...

  5. [C/C++标准库]_[0基础]_[使用fstream合并文本文件]

    场景: 1. 就是合并文本文件,而且从第2个文件起不要合并第一行. 2. 多加了一个功能,就是支持2个以上的文件合并. 3. 问题: http://ask.csdn.net/questions/192 ...

  6. [C/C++]_[0基础]_[static_cast,reinterpret_cast,dynimic_cast的使用场景和差别]

    场景: 1. C++的对象差别于C的原因是他们能够有继承关系, 方法有重载, 覆盖关系等, 他们的对象内存数据结构因此也比較复杂. 2. 非常多情况下我们须要一个父类来存储子类的指针对象进行通用方法的 ...

  7. [ATL/WTL]_[0基础]_[CBitmap复制图片-截取图片-平铺图片]

    场景: 1.当你须要截取图片部分区域作为某个控件的背景. 2.须要平铺图片到一个大区域让他自己主动放大时. 3.或者须要合并图片时. 代码: CDC sdc; CDC ddc; sdc.CreateC ...

  8. [C/C++标准库]_[0基础]_[交集和补集]

    场景: 1. 计算std::vector A和 std::vector B里的同样的元素, 用于保留不删除. 2. 计算std::vector A和 std::vector B里各自的补集, 用于删除 ...

  9. [C/C++标准库]_[0基础]_[优先队列priority_queue的使用]

    std::priority_queue 场景: 1. 对于一个任务队列,任务的优先级由任务的priority属性指明,这时候就须要优先级越高的先运行.而queue并没有排序功能,这时priority_ ...

随机推荐

  1. Django Model one

    models :URL---->http://www.cnblogs.com/wupeiqi/p/6216618.html null                     数据库中字段是否可以 ...

  2. luogu1242 新汉诺塔

    就是一步一步把大的往目标地放. #include <iostream> #include <cstdio> using namespace std; int fro[55], ...

  3. tensorflow笔记

    1.Estimator 进行编程的概览 要根据预创建的 Estimator 编写 TensorFlow 程序,您必须执行下列任务: 创建一个或多个输入函数. 定义模型的特征列. 实例化 Estimat ...

  4. LoadRunner web_set_sockets_option()--常用函数

    web_set_sockets_option()--常用函数 设置sockets的选项. intweb_set_sockets_option(const char * option,const cha ...

  5. php isset()与empty()详解

    bool isset(mixed var);[;mixed var[,...]] 这个函数需要一个变量名称作为参数,如果这个变量存在,则返回true,否则返回false. 也可以传递一个由逗号间隔的变 ...

  6. 排序算法总结 c描述

    概述 排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存. 我们这里说说八大排序就是内部排序. 当n较大, ...

  7. 2018天梯赛第一次训练题解和ac代码

    随着评讲的进行代码和题解会逐步放上来 2018天梯赛第一次训练 1001 : 进制转换 Time Limit(Common/Java):1000MS/10000MS     Memory Limit: ...

  8. 【Luogu】P3327约数个数和(莫比乌斯反演+神奇数论公式)

    题目链接 真TM是神奇数论公式. 注明:如无特殊说明我们的除法都是整数除法,向下取整的那种. 首先有个定理叫$d(ij)=\sum\limits_{i|n}{}\sum\limits_{j|m}{}( ...

  9. 二进制<1>

    Matrix67:位运算简介及实用技巧(一) 基础篇 什么是位运算?    程序中的所有数在计算机内存中都是以二进制的形式储存的.位运算说穿了,就是直接对整数在内存中的二进制位进行操作.比如,and运 ...

  10. 用jQuery实现搜索框的过滤效果

    遇到的问题: 1.动态添加了某些元素,在动态添加的某个元素上绑定事件失效 原因:因为需要绑定的元素的直接父元素也是动态添加的解决:向上为上一级父元素绑定事件 $(".check-box&qu ...