【C++】C++11

文章目录

  • C++11
    • 1. 统一的列表初始化
      • 1.1 {}初始化
    • 2. 声明
      • 2.1 auto
      • 2.2 decltype
      • 2.3 nullptr
    • 3. 右值引用和移动语义
      • 3.1 左值引用和右值引用
      • 3.2 左值引用与右值引用比较
      • 3.3 右值引用使用的场景和意义
      • 3.4 完美转发
    • 4. 可变参数模板
    • 5. lambda表达式
      • 5.1 函数对象与lambda表达式
    • 6. 线程库
      • 6.1 thread类的简单介绍
      • 6.2 线程函数参数
    • 7. 包装器
    • 8.bind

C++11

1. 统一的列表初始化

1.1 {}初始化

C++11扩大了用大括号括起来的列表的使用范围。使其适用于所有的内置类型和用户自定义的类型。使用初始化列表时,可以添加等号(=),也可以不添加

2. 声明

2.1 auto

C++11当中将其用于实现自动类型推断,这样要求必须进行显示初始化,让编译器将定义对象的类型设置为初始化值的类型。

2.2 decltype

将变量的类型声明为表达式指定的类型

2.3 nullptr

#ifndef NULL
#ifdef __cplusplus
#define NULL   0
#else
#define NULL   ((void *)0)
#endif
#endif

3. 右值引用和移动语义

3.1 左值引用和右值引用

传统的C++语法当中就有引用的概念,C++11当中增加了右值引用语法特性。无论是左值引用还是右值引用都是给变量起别名

什么是左值?什么是右值?

左值表示一个数据的表达式(如变量名或者解引用的指针),我们可以获取它的地址+可以对它赋值。左值可以出现在赋值符号的左边,右值不能出现在赋值符号的左边

int main() {// 以下都是左值int* p = new int(0);int b = 1;const int c = 2;// 一下都是左值的引用int*& rp = p;int& rb = b;const int& rc = c;int& value = *p;return 0;
}

什么是右值?什么是右值引用?

右值也是一个数据的表达式。如: 字面常量、表达式返回值、函数返回值(这个不能是左值引用返回)。右值不能出现在赋值符号的左边,右值不能取地址。右值引用就是对右值的引用,给右值起别名。


int main()
{double x = 1.1, y = 2.2;
// 以下几个都是常见的右值10;x + y;fmin(x, y);
// 以下几个都是对右值的右值引用int&& rr1 = 10;double&& rr2 = x + y;double&& rr3 = fmin(x, y);
// 这里编译会报错:error C2106: “=”: 左操作数必须为左值10 = 1;x + y = 1;fmin(x, y) = 1;return 0;
}

需要注意的是右值是不能取地址的,但是给右值取别名之后,会导致右值存储到特别的位置,并且可以取到该位置的地址。

int main() {double x = 1.1, y = 2.2;int&& rr1 = 10;const double&& rr2 = x + y;rr1 = 20;rr2 = 5.5; // 报错return 0;
}

3.2 左值引用与右值引用比较

左值引用总结:

  1. 左值引用只能引用左值,不能引用右值
  2. const左值引用既可以引用左值,也可以引用右值

右值引用总结:

  1. 右值引用只能引用右值,不能引用左值
  2. 右值引用可以引用move以后的左值

3.3 右值引用使用的场景和意义

左值引用的短板:

image-20230709205301133

只能使用传值返回,传值返回会导致至少一次拷贝构造

移动构造本质是将参数右值的资源窃取过来,占为已有。那么就不用做深拷贝了,所以叫做移动构造。就是窃取别人的资源来构造自己

不仅仅有移动构造,还有移动赋值

qsnpfu5bti-1688907511110.png

3.4 完美转发

模板当中的&& 不代表右值引用。而是万能引用。既能接收左值又能接收右值。模板的万能引用只是提供了同时接收左值引用又能接收右值引用。但是引用类型的唯一作用就是限制了接收的类型,后续引用中都退化成为了左值。如果在传递的过程当中保持左值或右值的属性,就需要这个完美转发了

forward保证了传参过程中的原生类型属性

强制生成默认函数的关键字default

比如我们提供了拷贝构造,就不会生成移动构造了,我们可以使用default关键字显示指定移动构造生成

禁止生成默认构造函数的关键字delete

4. 可变参数模板

template<class...Args>
void show(Args...args) {}

递归方式展开参数包:

// 递归终止函数
template <class T>
void ShowList(const T& t)
{cout << t << endl;
}
// 展开函数
template <class T, class ...Args>
void ShowList(T value, Args... args)
{cout << value <<" ";ShowList(args...);
}
int main()
{ShowList(1);ShowList(1, 'A');ShowList(1, 'A', std::string("sort"));return 0;
}

5. lambda表达式

lambda表达式实际上是一个匿名函数

lambda表达式的书写格式:

[capture-list] (parameters) mutable->return-type{statement}

int main() {int a = 3, b = 4;[=]{return a + b;};auto fun1 = [&](int c){b = a + c;};fun1(10);cout << b << " " << a << endl;// 复制捕捉xint x = 20;auto add_x = [x](int a) mutable {x *= 2;return a + x;};cout << add_x(10) << endl;cout << typeid(a).name() << endl;cout << typeid(add_x(10)).name() << endl;
}
  • [var]表示值传递方式,捕捉变量var
  • [=]:表示值传递方式,捕捉所有父作用域中的变量
  • [&var]:表示引用传递捕捉变量var
  • [&] : 表示引用传递所有父作用域中的变量
  • [this]:表示值传递方式捕捉当前的this指针

image-20230709213816350

5.1 函数对象与lambda表达式

函数对象又称为仿函数,是可以像函数一样使用的对象。就是在类中重载了operator()运算符的类对象

al3cwq0fkd-1688910086295.png

6. 线程库

6.1 thread类的简单介绍

在C++11之前,涉及到多线程的问题,都是和平台相关的。window和Linux都有自己的接口,这就让代码的移植性比较差。C++11当中最重要的特性就是对线程进行了支持,使C++在编程时不需要依赖第三方库

注意:

  1. 线程是操作系统中的概念,线程对象可以关联一个线程,用来控制线程以及获取线程的状态

  2. 当创建一个线程时, 没有提供线程函数,该对象实际没有对应任何线程

  3. 当创建一个线程对象后,并且线程关联线程函数,这个线程就被启动。与主线程一起运行。线程函数一般按照如下三种方式提供:

    1. 函数指针
    2. lambda表达式
    3. 函数对象

6.2 线程函数参数

线程函数参数是以值拷贝的方式拷贝到线程栈空间当中。因此即使线程参数为引用类型,在线程当中修改之后也还是不能修改外部实参。因为实际引用的是线程栈中的拷贝,不是外部实参

两个线程交替打印奇书偶数

#include "iostream"
#include "condition_variable"
#include "mutex"
#include "thread"using namespace std;//支持两个线程交替打印,t1打印奇数,t2一个打印偶数
int main(){mutex mtx;condition_variable cv;int n = 100;int x = 1;// 问题1:如何保证t1先运行,t2阻塞?// 问题2:如何防止一个线程不断运行?thread t1([&, n]() {while (true){unique_lock<mutex> lock(mtx);if (x >= 100)break;if (x % 2 == 0) // 偶数就阻塞{cv.wait(lock);}
//			cv.wait(lock, [&x]() {return x % 2 != 0; });cout << this_thread::get_id() << ":" << x << endl;++x;cv.notify_one();}});thread t2([&, n]() {while (true){unique_lock<mutex> lock(mtx);if (x > 100)break;if (x % 2 != 0) // 奇数就阻塞{cv.wait(lock);}
//			cv.wait(lock, [&x](){return x % 2 == 0; });cout << this_thread::get_id() << ":" << x << endl;++x;cv.notify_one();}});t1.join();t2.join();return 0;
}

7. 包装器

function包装器也叫适配器,我们来看看为什么需要包装器?本质上是一个类模板,也是一个包装器。

包装器的一个使用例子:

使用包装器之前的:

class Solution {
public:static int evalRPN(vector <string> &tokes){stack<int> s;for (auto&str : tokes){if (str == "+" || str == "-" || str == "*" || str == "/"){int right = s.top();s.pop();int left = s.top();s.pop();switch(str[0]){case '+':s.push(left + right);break;case '-':s.push(left - right);break;case '*':s.push(left * right);break;case '/':s.push(left / right);break;default:break;}}else{s.push(stoi(str));}}}
};

使用包装器之后:

class Solution {
public:static int evalRPN(vector <string> &tokes){stack<int> st;map<string, function<int(int, int)>> opFuncMap ={{"+", [](int i, int j){return i + j;}},{"-", [](int i, int j){return i - j;}},{"*", [](int i, int j){return i * j;}},{"/", [](int i, int j){return i / j;}}};for (auto& str : tokes){if (opFuncMap.find(str) != opFuncMap.end()){int right = st.top();st.pop();int left = st.top();st.pop();st.push(opFuncMap[str](left, right));}}}
};

8.bind

bind函数定义在头文件当中,是一个函数模板,它就像一个函数包装器(适配器)接收一个可调用对象生成一个新的可调用对象来“适应”原对象的参数列表。

一般而言,我么可以原本接收N个函数的参数的函数fn,通过绑定一些参数,返回一个接收M个参数(M可以大于N)

调用bind的一般形式是:auto newCallable = bind(callable, arg_list)

//表示绑定函数plus 参数分别由调用 func1 的第一,二个参数指定
std::function<int(int, int)> func1 = std::bind(Plus, placeholders::_1,placeholders::_2);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/5689.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

STM32入门之创建工程模板

1.STM32固件库的结构图如下。从图中可以看出&#xff0c;我们在配置STM32的固件库时需要配置用户层、CMSIS层的文件。配置库文件即正确的配置这些函数的文件。CMSIS(Cortex Microcontroller Software Interface Standard)是ARM公司提供的微控制器软件接口标准&#xff0c;所有使…

Data Structure, Algorithm,and Applications in C++

在学习这本书进阶内容之前&#xff0c;我们可以跟着它的第一章部分再巩固和复习。本书由Sartaj Sahni撰写&#xff0c;由王立柱和刘志红翻译。全书通俗易懂&#xff0c;内容丰富&#xff0c;是巩固C内容的不二选择。希望本文对各位有所帮助。 目录 1.函数与参数 1.1.传值参数…

C++初探

目录 经典开头 — C的历史 作用域运算符 using的用法 命名空间 - namespace 命名空间的基本使用 特殊的命名空间 - 无名命名空间 全部展开和部分展开 std — C所有的标准库都在std命名空间内 省缺值 - 默认参数 占位参数 内联函数 - inline 函数重载 函数重载的用…

【Unity2D】相机移动以及设置相机边界

添加相机 添加相机时&#xff0c;首先需要在unity中添加 Cinemachine 包 第一次使用这个包时&#xff0c;需要在Package Manager中搜索并安装 安装Camera Mechine包后&#xff0c;添加2D Camera 设置跟随对象为Ruby &#xff08;从Hierarchy中将Ruby拖动到Follow中&#xff0…

c函数学习

函数的概念 函数是c语言的功能单位&#xff0c;实现一个功能可以封装一个函数来实现。定义函数的时候一切以功能为目的&#xff0c;根据功能去定义函数的参数和返回值 函数的分类 从定义角度分类&#xff1a;库函数&#xff08;c库实现的&#xff09;&#xff0c;自定义函数&…

一、大数据技术之Flume(简介)

第1章 Flume概述 1.1 Flume定义 Flume是Cloudera提供的一个高可用的&#xff0c;高可靠的&#xff0c;分布式的海量日志采集、聚合和传输的系统。Flume基于流式架构&#xff0c;灵活简单。 1.2 Flume基础架构 Flume组成架构如下图所示。 1.2.1 Agent Agent是一个JVM进程&…

NLP实战8:图解 Transformer笔记

目录 1.Transformer宏观结构 2.Transformer结构细节 2.1输入 2.2编码部分 2.3解码部分 2.4多头注意力机制 2.5线性层和softmax 2.6 损失函数 3.参考代码 &#x1f368; 本文为[&#x1f517;365天深度学习训练营]内部限免文章&#xff08;版权归 *K同学啊* 所有&#…

在外远程NAS群晖Drive - 群晖Drive挂载电脑磁盘同步备份【无需公网IP】

文章目录 前言1.群晖Synology Drive套件的安装1.1 安装Synology Drive套件1.2 设置Synology Drive套件1.3 局域网内电脑测试和使用 2.使用cpolar远程访问内网Synology Drive2.1 Cpolar云端设置2.2 Cpolar本地设置2.3 测试和使用 3. 结语 前言 群晖作为专业的数据存储中心&…

【Hadoop 01】简介

目录 1 Hadoop 简介 2 下载并配置Hadoop 2.1 修改/etc/profile 2.2 修改hadoop-env.sh 2.3 修改core-site.xml 2.4 修改hdfs-site.xml 2.5 修改mapred-site.xml 2.6 修改yarn-site.xml 2.7 修改workers 2.8 修改start-dfs.sh、stop-dfs.sh 2.9 修改start-yarn.sh、s…

Elemui表单合并

原代码形式 <template><el-table:data"tableData"borderstyle"width: 100%"><el-table-columnprop"date"label"日期"width"180"></el-table-column><el-table-columnprop"name"label…

WebGL 概念和基础入门

WebGL 概念和基础入门 WebGL 是什么 对于 WebGL 百度百科给出的解释是 WebGL 是一种 3D 绘图协议&#xff0c;而对此维基百科给出的解释却是一种 JavaScript API。由于 WebGL 技术旨在帮助我们在不使用插件的情况下在任何兼容的网页浏览器中开发交互式 2D 和 3D 网页效果&…

react 实现小球加入购物车动画

代码 import React, { useRef } from react;const ProductLayout () > {const box useRef(null);const createBall (left, top) > {const ball document.createElement(div);ball.style.position absolute;ball.style.left left - 10 px;ball.style.top top - 1…

【机器学习】了解 AUC - ROC 曲线

一、说明 在机器学习中&#xff0c;性能测量是一项基本任务。因此&#xff0c;当涉及到分类问题时&#xff0c;我们可以依靠AUC - ROC曲线。当我们需要检查或可视化多类分类问题的性能时&#xff0c;我们使用AUC&#xff08;曲线下面积&#xff09;ROC&#xff08;接收器工作特…

使用 Vue 创建一个简单的 Loading 动画

使用 Vue 创建一个简单的 Loading 动画 1. 开始之前 确保 正确安装了 Vue 3知道如何启动一个新的 Vue 项目&#xff08;或在项目中使用Vue&#xff09;了解 Vue 3 的 Composition API&#xff08;本文将使用&#xff09; 2. 设计组件 该组件应该包含三个部分 控制逻辑旋转…

win10 安装 langchain-chatglm 遇到的问题

win10 安装 langchain-chatglm 避坑指南&#xff08;2023年6月21日最新版本&#xff09;_憶的博客-CSDN博客官网看起来安装很简单&#xff0c;网上教程也是&#xff0c;但实际上我耗费了两天时间&#xff0c;查阅了当前网络上所有可查阅的资料&#xff0c;重复「安装-配置-卸载…

Spring Security 构建基于 JWT 的登录认证

一言以蔽之&#xff0c;JWT 可以携带非敏感信息&#xff0c;并具有不可篡改性。可以通过验证是否被篡改&#xff0c;以及读取信息内容&#xff0c;完成网络认证的三个问题&#xff1a;“你是谁”、“你有哪些权限”、“是不是冒充的”。 为了安全&#xff0c;使用它需要采用 …

HideSeeker论文阅读

文章目录 3.1 Overview of Our System HideSeeker3.2 Visual Information Extraction3.3 Relation Graph Learning3.4 Hidden Object Inference 4 EVALUATIONS4.7 Summary 6 DISCUSSIONS AND CONCLUSION 3.1 Overview of Our System HideSeeker 我们设计了一种名为“HideSeeke…

个人博客系统(SSM版 前端+后端)

前言 在学习Servlet的时候,也写了一个博客系统,主要的就是使用servelet加Tomcat进行实现的,而这个项目 仅仅适合去学习Web项目开发的思想,并不满足当下企业使用框架的思想,进行学习过Spring,Spring Boot,Spring MVC以及MyBatis之后,我们就可以对之前的项目使用SSM框架的形式进行…

react+redux异步操作数据

reactredux异步操作数据 redux中操作异步方法&#xff0c;主要是&#xff1a; 1、借助createAsyncThunk()封装异步方法&#xff1b;2、通过extraReducers处理异步方法触发后的具体逻辑&#xff0c;操作派生的state 1、异步操作的slice import { createSlice, createAsyncThunk…

uniapp 之 微信小程序、支付宝小程序 对于自定义导航栏的不同

目录 前言 微信小程序 代码 支付宝小程序 首页配置文件 二级菜单页面 配置 总结 不同 相同 前言 小程序都是 uni-app 写的 不是原生 微信小程序 代码 pages.json文件中配置 重点&#xff1a; "navigationStyle": "custom", // 导航栏样式…