C++ 新特性 笔记
摘录
constexptr
总结来说,就是在c++11之前,要实现编译期数值计算需要繁琐的模板元编程。在c++11 中,可以是函数,在一句ruturn 语句中进行求值,函数中既不能有变量也不能有分之判断语句,限制较多。在C++17之后,则取消了大部分限制,比如可以有变量,可以有分支判断语句,但不能有goto,asm,try等语句。具体可以参考cppreference。
准确的说,constexpr函数是一种在编译期和运行期都能被调用并执行的函数。出于constexpr函数的这个特点,在C++11之后进行数值计算时,无论在编译期还是运行期我们都可以统一用一套代码来实现。编译期和运行期在数值计算这点上得到了部分统一。
什么是rvalues,lvalues,xvalues,glvalues和prvalues?
- lvalue(所谓的,历史上,因为左值可以出现在赋值表达式的左侧)表示一函数或一个对象。 [示例:如果E是指针类型的表达式,则*E 是一个左值表达式,引用要指向的对象或函数E 。另一个例子,调用返回类型为左值引用的函数的结果是左值。
- xvalue(一个“到期”值)也指一个对象,通常接近其寿命的末尾(使得其资源可以被移动,例如)。xvalue是涉及rvalue引用的某些表达式的结果。 [示例:调用返回类型为右值引用的函数的结果是xvalue。]
- glvalue (“广义”左值)是左值 或x值。
- rvalue(所谓的,历史上,因为右值可以出现在赋值表达式的右手侧)是x值,临时对象或子对象,或它们的不与一个对象相关联的值。
- prvalue(“纯”右值)是一个rvalue,这不是一个x值。 [示例:调用返回类型不是引用的函数的结果是prvalue]
lvalue 左值
当且仅当E指的是已经具有使其可在E外部访问的标识(地址,名称或别名)的实体时,表达式E属于左值类别。
#include <iostream>
int i=7;
const int& f(){
return i;
}
int main()
{
std::cout<<&"www"<<std::endl; // This address ...
std::cout<<&"www"<<std::endl; // ... and this address are the same.
"www"; // The expression "www" in this row is an **lvalue expression**, because it refers to the same entity ...
"www"; // ... as the entity the expression "www" in this row refers to.
i; // The expression i in this row is an lvalue expression, because it refers to the same entity ...
i; // ... as the entity the expression i in this row refers to.
int* p_i=new int(7);
*p_i; // The expression *p_i in this row is an lvalue expression, because it refers to the same entity ...
*p_i; // ... as the entity the expression *p_i in this row refers to.
const int& r_I=7;
r_I; // The expression r_I in this row is an lvalue expression, because it refers to the same entity ...
r_I; // ... as the entity the expression r_I in this row refers to.
f(); // The expression f() in this row is an lvalue expression, because it refers to the same entity ...
i; // ... as the entity the expression f() in this row refers to.
return 0;
}
xvalues 亡值
若表达式E属于xvalue类别,当且仅当它满足:
-无论是隐式调用还是显示调用,调用一个函数的结果返回一个对要返回的对象类型的引用的rvalue
int&& f(){
return 3;
}
int main()
{
f(); // 表达式 f() 是xvalue ,因为 f() 的返回类型是一个对象类型的引用的 rvalue.
return 0;
}
-或者,右值(rvalue)引用对象类型的cast
int main()
{
static_cast<int&&>(7); // 表达式static_cast<int&&>(7) , 其是右值引用对象类型的 cast.
std::move(7); // std::move(7) is equivalent to static_cast<int&&>(7).
return 0;
}
-类成员访问表达式指定 非引用类型的非静态数据成员, 其中对象表达式是 xvalue
struct As
{
int i;
};
As&& f(){
return As();
}
int main()
{
f().i; // f().i 是 xvalue, 因为 As::i 是 non-static data member of non-reference type, and the subexpression f() belongs to the xvlaue category.
return 0;
}
- 一种pointer-to-member表达式, 其中第一个操作数是 xvalue, 第二个操作数是指向数据成员的指针。
请注意,上述规则的效果是对命名rvalue引用被视为lvalues,对对象的未命名rvalue引用被视为xvalues; 对函数的右值引用被视为左值,无论是否命名。
#include <functional>
struct As
{
int i;
};
As&& f(){
return As();
}
int main()
{
f(); // The expression f() belongs to the xvalue category, because it refers to an unnamed rvalue reference to object.
As&& rr_a=As();
rr_a; // rr_a 是 lvalue category,因为它指的是一个命名的 rvalue 对象引用
std::ref(f); // n std::ref(f) 表达式是 lvalue , 因为它指的是一个命名的 rvalue 对象引用
return 0;
}
prvalue
当且仅当E既不属于左值也不属于xvalue类别时,表达式E属于prvalue类别。
struct As
{
void f(){
this; // this 是 **prvalue** 表达式。 注意:this 不是一个变量
}
};
As f(){
return As();
}
int main()
{
f(); // f() 表达式属于 prvalue category, 其既不属于 lvalue 也不属于 xvalue 类
return 0;
}
rvalue
当且仅当E属于xvalue类别或属于prvalue类别时,表达式E属于rvalue类别。
请注意,此定义表示当且仅当E指的是没有任何标识使其可在E之外访问的实体时,表达式E属于右值类别。
glvalues
当且仅当E属于lvalue类别或xvalue类别时,表达式E属于glvalue类别。
一个实用的规则
Scott Meyers 已出版的经验的一个非常有用的规则,从左值右值的区别。
如果可以获取表达式的地址,则表达式为左值。
如果表达式的类型是左值引用(例如,T&或const T&等),则该表达式是左值。
否则,表达式是右值。从概念上(通常也是实际上),rvalues对应于临时对象,例如从函数返回的或通过隐式类型转换创建的临时对象。大多数文字值(例如,10和5.3)也是右值。
C++ 新特性 笔记的更多相关文章
- html新特性笔记
HTML5知识总结 l 文档类型声明:<!DOCTYPE HTML> l 新绘制元素: Canvas:标签定义图形,比如图表和其他图像.该标签基于 JavaScript 的绘图 API ...
- C++ 新特性 笔记 2 右值引用
C ++ Rvalue引用说明 以下内容,主要是上述链接的摘要 介绍 Rvalue引用是C ++的一个特性,它是随C ++ 11标准添加的.使右值参考有点难以理解的是,当你第一次看到它们时,不清楚它们 ...
- ES 6 新特性笔记
let 与 var 的区别 功能 let var 块级作用域 ️ 变量提升 ️ 重复声明(相同作用域内) ️ var 没有块级作用域的解决方法 使用函数替代块级作用域,以保证变量的正常使用,如: .. ...
- CSS/CSS3语法新特性笔记
CSS层叠样式表 三大特性 层叠性:相同的样式会覆盖 继承性:属性可向下继承 优先级:范围越小权重越高 选择器 基础选择器 标签选择器 1 body { 2 color:#fff; 3 } 类选择器 ...
- java8新特性笔记
1.forEach(),遍历数据结构中的元素,括号内可以带一个闭包的方法 2.双冒号用法:forEach(this::doSchedule),如果运行环境是闭包,java允许使用双冒号的写法来直接调用 ...
- MySQL5.7新特性笔记
001.用户验证方式上的变化 MySQL5.7已经不要支持mysql_old_password验证插件,也不再支持old_password函数,也就说old_passwords也就不能被设置成1了.
- ES6 新特性(笔记)
1.定义变量 let a).块作用域 , 不同于var的函数作用域 b).不可以重复定义同一个变量名 注: {} ...
- C#新特性记录
C#6.0新特性笔记 Getter专属赋值 可以在构造函数中,给只有get的属性赋初始值. class Point { public int x { get; } public Point() { x ...
- C++ 11学习和掌握 ——《深入理解C++ 11:C++11新特性解析和应用》读书笔记(一)
因为偶然的机会,在图书馆看到<深入理解C++ 11:C++11新特性解析和应用>这本书,大致扫下,受益匪浅,就果断借出来,对于其中的部分内容进行详读并亲自编程测试相关代码,也就有了整理写出 ...
随机推荐
- Go项目实战:打造高并发日志采集系统(六)
前情回顾 前文我们完成了日志采集系统的日志文件监控,配置文件热更新,协程异常检测和保活机制. 本节目标 本节加入kafka消息队列,kafka前文也介绍过了,可以对消息进行排队,解耦合和流量控制的作用 ...
- wdScrollTab
wdScrollTab是一个采用jQuery实现的Tab面板,当标签太多超出页面时会自动滚动.支持iframe.ajax调用和动态加载内容.
- nexus私服库被误删如何恢复
恢复步骤: 1,登录nexus服务器,找到nexus安装目录(默认/usr/local/下): 2,找到sonatype-work/nexus/trash 下找到你删除的库: 3,copy到指定的so ...
- C#ModBus Tcp
C#ModBus Tcp 报文解析 上一篇博客已经完成 C#ModBus Tcp Master的实现 本篇主要对不同的功能码所发出的报文进行解析(包括请求报文及响应报文) 读操作 功能码 0x01 ...
- python 删除文件或文件夹
os.remove(path) 删除文件 path. 如果path是一个目录, 抛出 OSError错误.如果要删除目录,请使用rmdir(). remove() 同 unlink() 的功能是一样的 ...
- C语言Ⅰ博客作业08
这个作业属于那个课程 C语言程序设计II 这个作业要求在哪里 https://edu.cnblogs.com/campus/zswxy/CST2019-3/homework/9978 我在这个课程的目 ...
- AirFlow功能展示个人笔记
DAGs 查看您可以一目了然地查看成功.失败及当前正在运行的任务数量. 选中其中一个DAG 树视图 跨越时间的 DAG 的树表示.如果 pipeline(管道)延迟了,您可以很快地看到哪里出现了错误的 ...
- 基于SpringBoot从零构建博客网站 - 整合ehcache和开发注册登录功能
对于程序中一些字典信息.配置信息应该在程序启动时加载到缓存中,用时先到缓存中取,如果没有命中,再到数据库中获取同时放到缓存中,这样做可以减轻数据库层的压力.目前暂时先整合ehcache缓存,同时预留了 ...
- 【LOJ】#3044. 「ZJOI2019」Minimax 搜索
LOJ#3044. 「ZJOI2019」Minimax 搜索 一个菜鸡的50pts暴力 设\(dp[u][j]\)表示\(u\)用\(j\)次操作能使得\(u\)的大小改变的方案数 设每个点的初始答案 ...
- vue 模拟测试数据构建
等价=====================================