C++进阶(9)C++11

news2024/11/23 23:58:55

个人主页:仍有未知等待探索-CSDN博客

专题分栏:C++

目录

一、统一列表初始化

二、变量类型推导

1、auto

2、decltype

3、typeid

三、左值/右值

1、左值引用/右值引用(粗)

2、右值

3、右值引用(细)

1.移动构造、移动赋值

2.对于默认生成移动构造、移动赋值的条件  

四、lambda表达式

五、新的类功能 

六、模板的可变参数

1、计算形参对象包的数据个数?

2、打印出形参对象包里面的数据内容? 

3、容器中emplace系列

 七、包装器

1、function --- 类模板

2、bind --- 函数模板


一、统一列表初始化

一切可以用列表初始化。

注意:列表初始化和初始化列表是两个概念。

列表初始化是一个动作,而初始化列表是一种数据结构。

1、int arr[] = {1, 2, 3, 4, 5};
2、int x = {2}; // 正常的定义是: int x = 2; 但是为了统一列表初始化,上述也能支持
3、单参数的隐式类型转化
4、多参数的隐式类型转换 const A& aa1 = {2, 2};
5、vector<int> v = {1, 2, 3, 4, 5, 6};
6、构造:vector<int> v({1,2,3})
x自定义类型 = y类型 -> 隐式类型转换 x(y e)需要x支持y类型为参数的构造函数

二、变量类型推导

1、auto

自动推导变量类型

注意:

1、auto修饰的变量必须初始化。

2、auto类型不能用于函数参数。

3、auto类型不能用于定义数组。

4、auto无法推导模板参数。

5、auto不可以用于非静态成员变量

推导类型规则

// 当auto没有声明引用或者指针类型,auto类型推导则不带原变量的const和引用属性
// 输出
// 10
// 11
    const int a = 10;
    auto c = a;
    c++;
    cout << a << std::endl << c;


// 当auto类型声明了引用类型或者指针类型,auto类型推导带原变量的const和引用属性
	const int a = 10;
   	auto& c = a;
	c++; // 这句报错
	cout << a << std::endl << c; 

2、decltype

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

和auto的区别:

这个推导出来的类型可以定义变量。

list<int>::iterator it;
decltype(it) it2;

3、typeid

用于获取一个表达式或类型的运行时类型信息

list<int>::iterator it;
cout << typeid(it).name() << endl;

三、左值/右值

左值和右值不仅仅是一个值,也可能是有返回值的表达式

左值和右值的根本区别

1、能不能被取地址。

2、左值能被取地址。

3、右值不能被取地址。(匿名对象,字面常量,临时对象)

1、左值引用/右值引用(粗)

引用的意义:提高效率,减少拷贝。

左值引用:给左值起别名。

右值引用:给右值起别名。

注意:

  • 左值引用不能给右值起别名,但是const左值引用可以。
  • 右值引用不能给左值起别名,但是可以给move之后的左值起别名。

2、右值

右值包括:匿名对象,字面常量,临时对象。

右值分为两种

1、纯右值。(内置类型)

2、将亡值。(自定义类型)

class A
{};
// 纯右值
10、'e'、3.14
// 将亡值
A()

3、右值引用(细)

注意:

右值引用本身是左值。

只有右值引用本身处理成左值,才能实现移动构造和移动复制,转移资源。

1.移动构造、移动赋值

移动构造和移动赋值的本质就是转移资源

  • 右值引用的属性如果是右值,那么移动构造和移动复制,要转移资源的语法逻辑是矛盾的,右值是不能被改变的(右值带有const属性)。
  • 右值引用本身是左值。只有右值引用本身处理成左值,才能实现移动构造和移动复制,转移资源。
  • 深拷贝的类才有转移资源的移动系列函数。

说白了转移资源就是把将亡值的数据直接和类内成员变量进行交换。

#include <iostream>
#include <string>
using namespace std;

class A
{
private:
	string _a;
public:
	// 强制生成A()
	A() = default;
	// 类A的拷贝构造 --- 深拷贝
	A(const string& a)
		:_a(a)
	{}
	// 类A的赋值重载
	A& operator=(const string& a)
	{
		_a = a;
		return *this;
	}
	// 移动构造
	A(string&& a)
	{
		swap(_a, a);
	}
	// 移动赋值
	A& operator=(string&& a)
	{
		swap(_a, a);
	}
};
int main()
{
	// 拷贝构造、赋值
	A a;
	string b = "abcd";
	a = b;
	A c(b);

	// 移动构造、移动赋值
	A d("11111");
	A e = string("11111");

	return 0;
}

2.对于默认生成移动构造、移动赋值的条件  

  • 如果你没有实现移动构造函数,且没有实现析构函数、拷贝构造,拷贝复制重载中的任意一个,那么编译器会默认生成一个默认的移动构造。对于内置类型成员会执行逐成员按字节拷贝;对于自定义类型成员,如果该自定义类型实现了移动构造函数就执行,刚没有实现就调用拷贝构造。
  • 如果你没有实现移动赋值重载,且没有实现析构函数、拷贝构造,拷贝复制重载中的任意一个,那么编译器会默认生成一个默认的移动赋值重载。对于内置类型成员会执行逐成员按字节拷贝;对于自定义类型成员,如果该自定义类型实现了移动赋值重载就执行,刚没有实现就调用拷贝赋值。
  • 如果提供了移动构造函数或者移动赋值,编译器则不会自动提供拷贝构造和拷贝赋值

四、lambda表达式

匿名函数对象

        

#include <iostream>
using namespace std;

int main()
{
	int c = 2, d = 1;
	// 捕捉列表,捕捉变量
	auto add = [c, d](int a, int b)->int {return a + b + c + d; };
	cout << add(1, 2) << endl;
	cout << "-------------------------------------------------------" << endl;

	// 默认的捕捉列表里面的变量具有const性,且是传值
	// 这么写会报错:表达式必须是可修改的左值
	auto swap = [c, d]()->void
		{
			int t = c;
			d = c;
			c = t;
		};
	cout << "-------------------------------------------------------" << endl;

	// 这样就没有什么问题,因为mutable取消了const性
	// 但是c、d仍无法交换
	auto swap = [c, d]()mutable->void
		{
			int t = c;
			c = d;
			d = t;
		};
	cout << c << " " << d << endl;
	swap();
	cout << c << " " << d << endl;
	cout << "-------------------------------------------------------" << endl;

	// 这么写就能正常的交换
	auto swap = [&c, &d]()mutable->void
		{
			int t = c;
			c = d;
			d = t;
		};
	cout << c << " " << d << endl;
	swap();
	cout << c << " " << d << endl;

	return 0;
}

五、新的类功能 

  • 强制自动生成默认函数 --- default
    class A
    {
    private:
    	int _a;
    public:
    	A() = default; // 强制生成无参构造函数
    	A(int a)
    		:_a(a)
    	{}
    };

  • 禁止生成函数 --- delete

    class A
    {
    private:
    	int _a;
    public:
    	A() = default; // 强制生成无参构造函数
    	A(int a)
    		:_a(a)
    	{}
    	A& operator=(int a) = delete; // 禁止生成默认函数
    };

六、模板的可变参数

1、计算形参对象包的数据个数?

sizeof...(args)

2、打印出形参对象包里面的数据内容? 

 模板的可变参数应该是在编译的时候进行解析的,而不是在运行时进行解析

如下是错误示例:

template <class ...Args>
void print(Args... args)
{
	// 错误做法读取args
	// error C3520: “args”: 必须在此上下文中扩展参数包
	// 不支持、不匹配
	// 参数包是在编译时逻辑
	// 代码是运行时逻辑
	for (int i = 0; i < sizeof...(args); i++)
	{
		cout << args[i] << " ";
	}
}

如下是正确示范:

#include <iostream>
using namespace std;

// 用于判断参数包是否已经读完
// 不能用数据个数来判断是否已经结束,因为sizeof是运行的时候才进行替换
// 而这个打印参数包内容是在编译时就已经展开完毕
void cpp_print()
{
	cout << endl;
}
// 打印主体
// 第一个参数用一个模板进行接收,从而获取到参数包内容
template <class T, class ...Args>
void cpp_print(T val, Args... args)
{
	cout << val << endl;
	cpp_print(args...);
}

// 外壳函数
template <class ...Args>
void print(Args... args)
{
	// 调用主体函数,传参的时候要传参数包
	// 虽然调用的函数模板参数有两个,但是可以传一个参数包,自动把参数包第一个参数匹配到val中,剩下的还传到args参数包中
	cpp_print(args...);
}

int main()
{
	print(1, "22", 3.333);

	return 0;
}

3、容器中emplace系列

容器中emplace系列的参数都是传的参数包。

所以当你要传入多个参数的时候,建议使用emplace系列函数。

list<pair<string, int>> it;

it.push_back({ "xxxxxx" , 1});
it.emplace_back("bbbbbbb", 2);

 七、包装器

包装可调用对象。

下列的头文件都在<functional>。

1、function --- 类模板

// 包装类包装类内成员函数
#include <iostream>
#include <functional>

using namespace std;

class Plus
{
public:
    static int func1(int a, int b)
    {
        return a + b;
    }
    double func2(double a, double b)
    {
        return a + b;
    }

};
int main()
{
    // 包装静态的成员函数
    function<int(int, int)> f1 = &Plus::func1;
    cout << f1(1, 2) << endl;
    // 包装飞机静态的成员函数
    // 第一种方式
    function<double(Plus*, double, double)> f2 = &Plus::func2;
    Plus p2;
    cout << f2(&p2, 1.1, 2.2) << endl;
    // 第二种方式
    function<double(Plus, double, double)> f3 = &Plus::func2;
    cout << f3(Plus(), 1.1, 2.2) << endl;

    return 0;
}

2、bind --- 函数模板

包装可调用对象和参数包。

#include <iostream>
#include <functional>
using namespace std;


class Sub
{
public:
    int sub(int a, int b)
    {
        return a - b;
    }
};

int main()
{
    auto f1 = bind(&Sub::sub, placeholders::_1, placeholders::_2, placeholders::_3);
    cout << f1(Sub(),  10, 5) << endl;

    // bind可以调整可调用对象的参数个数和顺序
    auto f2 = bind(&Sub::sub, placeholders::_1, placeholders::_3, placeholders::_2);
    cout << f2(Sub(), 10, 5) << endl;

    // 调整对调用对象的参数个数
    auto f4 = bind(&Sub::sub, Sub(), placeholders::_1, placeholders::_2);
    cout << f4(10, 5) << endl;
    Sub sub;
    auto f5 = bind(&Sub::sub, &sub, placeholders::_1, placeholders::_2);
    cout << f5(10, 5) << endl;

    return 0;
}

谢谢大家!!!

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

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

相关文章

135.分发糖果,遍历方向+candy选取的详解

力扣135分发糖果 题目思路代码 题目 https://leetcode.cn/problems/candy/description/ 老师想给孩子们分发糖果&#xff0c;有 N 个孩子站成了一条直线&#xff0c;老师会根据每个孩子的表现&#xff0c;预先给他们评分。 你需要按照以下要求&#xff0c;帮助老师给这些孩子…

【Python机器学习】朴素贝叶斯——使用Python进行文本分类

目录 准备文本&#xff1a;从文本中构建词向量 训练算法&#xff1a;从词向量计算概率 测试算法&#xff1a;根据现实情况修改分类器 准备数据&#xff1a;文档词袋模型 要从文本中获取特征&#xff0c;需要先拆分文本。这里的特征是来自文本的词条&#xff0c;一个词条是字…

大脑网络交互分析:公式与应用

大脑网络交互分析&#xff1a;公式与应用 核心概念与重要性 大脑网络交互分析是神经科学研究中的重要领域&#xff0c;它关注大脑不同区域之间的连接与交互方式。通过分析大脑网络&#xff0c;我们可以理解大脑如何处理和整合信息&#xff0c;进而揭示认知、情感和行为的神经…

java 集合框架-map(键值对集合)

一、Map接口 (键值对集合) 1.实现类 (1).线程不安全 HashMap 1.特点: ①无序 ②查找效率高&#xff1a;根据key&#xff0c;查找value 2.数据结构&#xff1a;数组&#xff08;哈希表&#xff09; 链表&#xff08;链地址法解决哈希表冲突&#xff09; 红黑树&#xff0…

UDP的报文结构及其注意事项

1. 概述 UDP&#xff08;User Datagram Protocol&#xff09;是一种无连接的传输层协议&#xff0c;它提供了一种简单的数据传输服务&#xff0c;不保证数据的可靠传输。在网络通信中&#xff0c;UDP通常用于一些对实时性要求较高、数据量较小、传输延迟较低的应用&#xff0c…

大数据的数据质量有效提升的研究

大数据的数据质量有效提升是一个涉及多个环节和维度的复杂过程。以下是从数据采集、处理、管理到应用等方面&#xff0c;对大数据数据质量有效提升的研究概述&#xff1a; 一、数据采集阶段 明确采集需求&#xff1a;在数据采集前&#xff0c;需明确数据需求&#xff0c;包括…

Mike21粒子追踪模型particle tracking如何展示粒子轨迹

前言&#xff1a; 随着模型的推广&#xff0c;模型的很多模块也问的多了起来&#xff0c;PT粒子追踪模块最近群友也在问&#xff0c;结果算了出来&#xff0c;却实现不了展示运动轨迹。今天就写段简单的PT后处理的方法吧。 注意&#xff1a;MIKE21输出模块中不但输出了关于水…

3个管人绝招,让下属心服口服

管人不能瞎管&#xff0c;手段很重要&#xff1a;3个管人绝招&#xff0c;让下属心服口服 一&#xff1a;差异化管理&#xff0c;玩弄人性 谁赞成&#xff0c;谁反对&#xff0c;看清楚谁顺从自己&#xff0c;谁反对自己之后&#xff0c;接下来要做的便是区别对待。 给听话的…

简单的CSS样式

样式分为三种 内部样式&#xff1a;写在html文件里的样式叫内部样式 内联样式&#xff1a;写在需要的标签中 外部样式&#xff1a;写在外部css文件里 可以通过不同的选择器来选择设置指定组件的样式&#xff1a; <style>/* 写在html文件里的样式叫内部样式 *//* 选择器 *…

PEFT LoRA 介绍(LoRA微调使用的参数及方法)

一 PEFT LoRA 介绍 官网简介如下图&#xff1a; 翻译过来是&#xff1a;低秩自适应(LoRA)是一种PEFT方法&#xff0c;它将一个大矩阵在注意层分解成两个较小的低秩矩阵。这大大减少了需要微调的参数数量。 说的只是针对注意力层&#xff0c;其实我自己平时微调操作注意力层多…

一款功能强大的视频编辑软件会声会影2023

会声会影2023是一款功能强大的视频编辑软件&#xff0c;由加拿大Corel公司制作&#xff0c;正版英文名称为‌Corel VideoStudio。它具备图像抓取和编修功能&#xff0c;可以处理和转换多种视频格式&#xff0c;如‌MV、‌DV、‌V8、‌TV和实时记录抓取画面文件。会声会影提供了…

微服务上(黑马)

文章目录 微服务011 认识微服务1.1 单体架构1.2 微服务1.3 SpringCloud 2 微服务拆分2.1 熟悉黑马商城2.2 服务拆分原则2.2.1.什么时候拆2.2.2.怎么拆 2.3 拆分服务2.3.1 拆分商品管理功能模块2.3.2 拆分购物车功能模块 2.4 远程调用2.4.1 RestTemplate2.4.2.远程调用 2.5 总结…

SpringBoot-21 SpringBoot微服务的发布与部署(3种方式)

基于 SpringBoot 的微服务开发完成之后&#xff0c;现在到了把它们发布并部署到相应的环境去运行的时候了。 SpringBoot 框架只提供了一套基于可执行 jar 包&#xff08;executable jar&#xff09;格式的标准发布形式&#xff0c;但并没有对部署做过多的界定&#xff0c;而且为…

25届最近5年广东工业大学自动化考研院校分析

广东工业大学 目录 一、学校学院专业简介 二、考试科目指定教材 三、近5年考研分数情况 四、近5年招生录取情况 五、最新一年分数段图表 六、初试大纲复试大纲 七、学费&奖学金&就业方向 一、学校学院专业简介 二、考试科目指定教材 1、考试科目介绍 2、指定教…

【在排序数组中查找元素的第一个和最后一个位置】python刷题记录

R2-分治 有点easy的感觉&#xff0c;感觉能用哈希表 class Solution:def searchRange(self, nums: List[int], target: int) -> List[int]:nlen(nums)dictdefaultdict(list)#初始赋值哈希表&#xff0c;记录出现次数for num in nums:if not dict[num]:dict[num]1else:dict[…

(深层与双向)循环神经网络

一、深层循环神经网络 1、对于循环神经网络 2、对于深层&#xff0c;要得到更多的非线性&#xff0c;就像多层感知机&#xff08;MLP&#xff09;。 &#xff08;1&#xff09;浅层与深层对比 这是具有&#x1d43f;个隐藏层的深度循环神经网络&#xff0c; 每个隐状态都连续…

【QT】QT 系统相关(事件、文件、多线程、网络、音视频)

一、Qt 事件 1、事件介绍 事件是应用程序内部或者外部产生的事情或者动作的统称。在 Qt 中使用一个对象来表示一个事件。所有的 Qt 事件均继承于抽象类 QEvent。事件是由系统或者 Qt 平台本身在不同的时刻发出的。当用户按下鼠标、敲下键盘&#xff0c;或者是窗口需要重新绘制…

《python程序语言设计》第6章14题 估算派值 类似莱布尼茨函数。但是我看不明白

这个题提供的公式我没看明白&#xff0c;后来在网上找到了莱布尼茨函数 c 0 for i in range(1, 902, 100):a (-1) ** (i 1)b 2 * i - 1c a / bprint(i, round(4 / c, 3))结果 #按题里的信息&#xff0c;但是结果不对&#xff0c;莱布尼茨函数到底怎么算呀。

【计算机网络】TCP协议详解

欢迎来到 破晓的历程的 博客 ⛺️不负时光&#xff0c;不负己✈️ 文章目录 1、引言2、udp和tcp协议的异同3、tcp服务器3.1、接口认识3.2、服务器设计 4、tcp客户端4.1、客户端设计4.2、说明 5、再研Tcp服务端5.1、多进程版5.2、多线程版 5、守护进程化5.1、什么是守护进程5.2…

Javascript面试基础6(下)

获取页面所有checkbox 怎样添加、移除、移动、复制、创建和查找节点 在JavaScript中&#xff0c;操作DOM&#xff08;文档对象模型&#xff09;是常见的任务&#xff0c;包括添加、移除、移动、复制、创建和查找节点。以下是一些基本的示例&#xff0c;说明如何执行这些操作&a…