为什么每个STL容器都具有将其定义为成员函数的交换函数

Why does every STL container have a swap function defined as a member function?

本文关键字:函数 定义 成员 交换 STL 为什么      更新时间:2023-10-16

考虑stl中的queue容器。

我的理解是,<algorithm>标头中可用的swap()可以正常工作。

我知道swap()只能从表面上复制queue实例,也就是说,只有frontrear指针将与size以及其他数据成员一起复制。

两个队列中的条目不会物理交换位置,但是我不明白为什么在任何情况下都可以在任何情况下都可以换取,因为指针和大小交换了,两个队列将有效地交换。

<</p> <</p>

在C 11引入移动语义之前,std::swap的通用实现别无选择,只能进行两份副本。从概念上讲,这是:

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

请注意,此通用std::swap不知道关于传递对象内部的任何知识(例如,可以使用任意用户类型调用),因此必须进行副本。请注意,对于容器,这意味着复制元素。

提供优化的成员函数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的特定类型过载。这些过载的作用就是只需在其中一个操作数上调用优化的swap成员功能即可。这样,您拥有两全其美的最好的:一个通用的免费功能swap,可以用任何东西调用,但它已经优化了标准库所知道的所有内容的实现。

可以直接放弃成员功能并在std::swap内部直接提供优化的实现,但这意味着他们可能需要与之交友,并且可以将其视为用户代码可访问更糟糕的情况。

由于免费的std::swap对每个容器的过载都有过载,因此成员函数swap s并不是真正必要的。免费的过载可能已被声明为friend s,并执行所有实现的特定于容器特定的魔术以进行有效的交换。

,他们调用成员swap s。我想这允许在如何调用这些功能方面具有额外的灵活性,并且可以节省大量friend声明。

我不知道还有什么。

当统一呼叫语法提案(2014年版本的Bjarne Stroustrup)终于被采用后,经过一些最终调整后,您的问题将在std::swap(my_queue, another_queue)my_queue.swap(other_queue)的意义上变得无所适从。完全相同的函数。不幸的是,C 17不会发生这种情况。也许在C 20中?一个人可以做梦...