c – 为什么每个STL容器都有一个定义为成员函数的交换函数?

考虑STL中的队列容器.

我的理解是< algorithm>中可用的swap().标题会工作得很好.

我知道swap()只会表面复制队列实例,也就是说,只会复制前后指针,以及大小和其他数据成员.

两个队列中的条目不会在物理上交换位置,但我不明白为什么在任何情况下这都是必要的,因为一旦指针和大小被交换,两个队列将被有效地交换.

解决方法

在C 11引入移动语义之前,std :: swap的通用实现别无选择,只能做两个副本.从概念上讲,这个:
template <class T>
void swap(T &a,T &b)
{
  T t(a);
  a = b;
  b = t;
}

请注意,这个通用的std :: swap对传入的对象的内部结构一无所知(例如,因为它可以使用任意用户类型调用),因此必须进行复制.请注意,对于容器,这意味着复制元素.

因此,提供优化的成员函数交换只是重新指向一些内部指针,这是一个巨大的性能胜利.

由于引入了移动语义,因此可以使用移动使通用交换更有效.再次,概念上:

template <class T>
void swap(T &a,T &b)
{
  T t(::std::move(a));
  a = ::std::move(b);
  b = ::std::move(t);
}

当然,在实践中,它可能有关于移动操作涉及非投掷的要求,以及各种额外的位.

使用移动语义,优化的成员版本可能不像以前那么重要.但是仍然有可能通过了解类型的确切实现细节,交换它可能比三个通用移动更快.

除了上面的讨论之外,请注意标准库中定义的几乎所有类型都存在std :: swap的特定于类型的重载.这些重载的作用只是在其中一个操作数上调用优化的交换成员函数.这样,你就拥有了两全其美的优势:一个通用的自由函数交换,可以用任何东西调用,但它已经优化了标准库所知道的所有实现.

有可能放弃成员函数并直接在std :: swap重载内部提供优化的实现,但这意味着他们可能需要被人们理解,并且可能被认为对用户代码更容易访问.

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...