微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

原文地址:https://www.jb51.cc/c/119227.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐