考虑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重载内部提供优化的实现,但这意味着他们可能需要被人们理解,并且可能被认为对用户代码更容易访问.