c++11 用 std::swap vs operator=(T&&) 清除容器

Posted

技术标签:

【中文标题】c++11 用 std::swap vs operator=(T&&) 清除容器【英文标题】:c++11 clearing a container with std::swap vs operator=(T&&) 【发布时间】:2014-02-01 20:00:31 【问题描述】:

在 c++11 中哪种方式更好/更快地清除容器(例如队列):

void clean()

   std::queue<int> empty_q;
   std::swap(q_to_clear, empty_q);

或使用 operator=(Q &&) (比 swap 快?)

void clean ()

    q_to_clear = std::queue<int>;

或者本质上是一样的?

【问题讨论】:

【参考方案1】:

这可能几乎没有什么区别,但是移动分配要求临时源队列在被移动后需要建立一个新的空状态,您可以通过交换来避免这种情况。你可以编写如下交换:

std::queue<int>().swap(q_to_clear);

【讨论】:

"...move-assignment 要求临时源队列需要建立一个新的、空状态" 嗯...实际上,move-assignment 不需要。搬出的容器不保证/不需要变空。【参考方案2】:

C++11-ness 提升到极致:

decltype(q_to_clear)().swap(q_to_clear);

也适用于其他 std:: 容器。

compact memory 语法很酷:

decltype(q_to_compact)(q_to_compact).swap(q_to_compact);

【讨论】:

compact memory版本有什么用? ...啊,你复制了q_to_compact 会更清楚地说明这一点,还是你害怕初始化列表问题? @Yakk - 这是为了释放过度分配的内存。 std::vector 的默认分配策略是在容量耗尽时将容量增加 x2,因此最终可能会浪费一半的内存。因此,您从现有向量创建一个临时向量(该向量将具有与大小完全匹配的容量),交换是您想要压缩的向量的胆量,并让它超出范围。

以上是关于c++11 用 std::swap vs operator=(T&&) 清除容器的主要内容,如果未能解决你的问题,请参考以下文章

读书笔记_Effective_C++_条款二十五: 考虑写出一个不抛出异常的swap函数

将 std::iter_swap 用于 std::optional

使用零大小数组的 std::swap() 编译错误?

Iterator invalidation(迭代器失效)

swap函数

使用宏来专门化std :: swap