C++11·部分重要语法III

目录

emplace

emplace和push区别

例:list的模拟实现部分代码

默认移动构造和移动赋值

默认函数的控制

小知识


emplace

C++11以后STL容器新增了emplace系列接口,均为模版可变参数,功能是插入,但总体而言比push和insert更高效,而且有更新的玩法,假设一个容器container<T>,emplace可以支持直接插入构造T对象的参数,可以直接在容器空间构造T对象。

emplace和push区别

对于非move的右值,emplace都是直接在容器中构造,push要先在容器外构造再移动构造。

例:list的模拟实现部分代码

template<class T>
struct list_node //对于
{
list_node<T>* _prev = nullptr;
list_node<T>* _next = nullptr;
T _val;

list_node(T&& val = T())
:_val(move(val))
{ }

template<class... Args>
list_node(Args&&... args)
:_val(std::forward<Args>(args)...) //使用完美转发,否则右值表达式变左值
{}

};

list类中的insert和emplace

iterator insert(iterator pos, const T& val)
{
Node* newnode = new Node(val);

newnode->_prev = pos._node->_prev;
newnode->_next = pos._node;
pos._node->_prev->_next = newnode;
pos._node->_prev = newnode;

_size++;
return iterator(newnode);
}

iterator insert(iterator pos, T&& val)
{
Node* newnode = new Node(move(val));

newnode->_prev = pos._node->_prev;
newnode->_next = pos._node;
pos._node->_prev->_next = newnode;
pos._node->_prev = newnode;

_size++;
return iterator(newnode);
}

template<class... Args>
void emplace_back(Args&&... args)
{
emplace(end(),std::forward<Args>(args)...);//包扩展的第二种展开方式
}

template<class... Args>
iterator emplace(const iterator pos,Args&&... args)
{
Node* newnode = new Node(std::forward<Args>(args)...);//包扩展的第二种展开方式,这里可以将参数直接在结点类中构造成新结点,只需一次构造即可。

newnode->_prev = pos._node->_prev;
newnode->_next = pos._node;
pos._node->_prev->_next = newnode;
pos._node->_prev = newnode;

_size++;
return iterator(newnode);
}

默认移动构造和移动赋值

C++类中原本有6个默认成员函数:构造函数/析构函数/拷贝构造函数/拷贝赋值重载/取地址重载/const取地址重载。

C++11中新增了两个默认成员函数,移动构造函数和移动赋值运算符重载。

规则:1.如果未实现移动构造函数,且未实现析构函数、拷贝构造、拷贝赋值重载中的任意一个,编译器就会自动生成一个默认移动构造函数。对内置类型执行浅拷贝,对自定义类型调移动构造,如果未实现移动构造,那会调拷贝构造。

2.如果未实现移动赋值重载函数,且未实现析构函数、拷贝构造、拷贝赋值重载中的任意一个,编译器会自动生成一个默认移动赋值函数。对内置类型执行浅拷贝,对自定义类型调移动赋值,如果未实现移动赋值,调拷贝赋值。(默认移动赋值和默认移动构造相似)

注:如果写了移动构造 or 移动赋值,编译器就不会自动生成拷贝构造和拷贝赋值。

默认函数的控制

1.如果想要使用某个默认函数,但这个函数未默认生成。例:写了拷贝构造,就不会生成移动构造了。 那么可以使用default关键字显示指定移动构造生成。

类名(右值引用参数列表) {} = default 就是函数声明+ = default

2.如果想要限制某些默认函数的生成,C++11中可以在函数声明后加 = delete,该语法指示编译器不生成对应函数的默认版本,称=delete修饰的函数为删除函数。

小知识

1.模运算% 要求两边为整数 结果与第一个操作数的正负相同。

如:-5%3 = -2 -5%-3 = -2 5%-3 = 2

2.'1'占一个字节 "1"占两个字节,'\0'也占字节

相关推荐
NX-二次开发12 分钟前
UG CAM API 获取、设置切削层中的切削方式类型方法,如设置仅底面、恒定、临界深度的类型
c++
沉沙丶16 分钟前
关于matlab分析电流THD的一些探究和记录
开发语言·matlab·电机控制·foc·永磁同步电机·模型预测·预测控制
chase。17 分钟前
Python包构建工具完全指南:python -m build 使用详解
开发语言·chrome·python
SuperEugene22 分钟前
前端 utils 工具函数规范:拆分 / 命名 / 复用全指南,避开全局污染等高频坑|编码语法规范篇
开发语言·前端·javascript
祝大家百事可乐22 分钟前
嵌入式——02 数据结构
c++·c#·硬件工程
Yu_Lijing24 分钟前
基于C++的《Head First设计模式》笔记——生成器模式
c++·笔记·设计模式
古城小栈30 分钟前
Go 底层代码的完整分类
开发语言·后端·golang
耳冉鹅34 分钟前
Go无锁共享内存环形缓冲区设计
开发语言·golang
计算机安禾44 分钟前
【C语言程序设计】第36篇:二进制文件的读写
c语言·开发语言·c++·算法·github·visual studio code·visual studio
子非鱼@Itfuture1 小时前
try-catch和try-with-resources区别是什么?try{}catch(){}和try(){}catch(){}有什么好处?
java·开发语言