可变参数模版
4.4 emplace系列接口

通过前面的学习,我们知道emplace_back和push_back的区别其实不是很大,真正的区别就是:

  • emplace_bakc是一个可变参数模版,而push_back只是一个普通的函数

emplace_back可以传参数包进行构造,而push_back不能传参数包,要么是传插入的对象,或者是进行隐式类型转换

ok,当我们了解了这些,我们就来实现一个emplace_back:

4.5 emplace和emplace_back在list中的模拟实现

代码语言:javascript

AI代码解释

template<class ...Args>
void emplace_back(Args... args)
{
	emplace(end(), forward<Args>(args)...);
}
template<class ...Args>
iterator emplace(iterator pos,Args&&... args)
{
	Node* cur = pos._node;
	Node* newnode = new Node(forward<Args>(args)...);
	Node* prev = cur->_prev;
	// prev newnode cur
	prev->_next = newnode;
	newnode->_prev = prev;
	newnode->_next = cur;
	cur->_prev = newnode;
	return iterator(newnode);
}

ok,当我们实现了emplace_back和emplace接口后,我们就要实现相应的可变模板参数版本的构造节点的代码:

代码语言:javascript

AI代码解释

template <class... Args>
ListNode(Args&&... args)
	: _next(nullptr)
	, _prev(nullptr)
	, _data(std::forward<Args>(args)...)
{}

ok,这样改完之后,我们就可以使用emplace_back进行尾插操作。

但是,当我们加上emplace_back后,push_back就不能使用万能引用版本的尾插,为什么?

  1. 库中并没有把push_back写成泛型化,因为有了emplace_back就没有必要将push_back写成泛型化
  2. 要兼容以前的代码,我们只能写一个左值版本和一个右值版本的push_back代码

总结:有了emplace_back,就不需要这个万能引用版的push_back,直接使用左值版本和右值版本的push_back

emplace_back总体而言是更高效,推荐以后使用emplace系列替代insert和push系列

  • 除此之外:emplace_back和push_back的用法是不能混着的~

五、C++11中类的新功能
5.1 默认的移动构造和移动赋值

原来的C++类中,有6个默认成员函数:构造、析构、拷贝构造、赋值重载、取地址重载、const取地址重载,最重要的是前4个,后2个用处不大

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐