现代C++特性深度探索:模板扩展、类增强、STL更新与Lambda表达式
·
可变参数模版
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就不能使用万能引用版本的尾插,为什么?
- 库中并没有把push_back写成泛型化,因为有了emplace_back就没有必要将push_back写成泛型化
- 要兼容以前的代码,我们只能写一个左值版本和一个右值版本的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个用处不大
更多推荐



所有评论(0)