为什么每个STL容器都具有将其定义为成员函数的交换函数
Why does every STL container have a swap function defined as a member function?
考虑stl中的queue
容器。
我的理解是,<algorithm>
标头中可用的swap()
可以正常工作。
我知道swap()
只能从表面上复制queue
实例,也就是说,只有front
和rear
指针将与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中?一个人可以做梦...
- 不同翻译单元中不可重载的非内联函数定义
- Visual Studio中的函数声明和函数定义问题
- 编写代码时C++出现错误:错误 1 错误 C2601:'circle':本地函数定义是非法的
- 具有enable_if外部类原型的模板类构造函数定义
- 类的前向声明之后的类成员函数定义,在类声明之前
- 为函数定义符号不明确的指针参数
- C++模板专用化 - 无法匹配函数定义
- 错误:在第 6 行'{'标记之前,此处不允许使用函数定义
- 找不到 #define 的函数定义
- 根据类型特征更改函数定义?
- 将抽象基类中的所有纯虚函数定义为 varaidaic 模板
- 命名空间更改函数定义
- "Type&"与C++函数定义中的"Type*"
- C++:为什么允许在另一个函数中声明函数,而不允许在函数定义中声明?
- 如何从 C++ 中的现有模板函数定义新函数
- 私有在函数定义/实现的返回值范围内是什么意思 (c++)?
- 越界成员函数定义是否需要一个完全限定的类名,直到全局范围
- 为什么c++允许成员函数定义中实例的私有成员访问
- Qt基类函数定义
- C++函数定义中参数列表后面额外一对括号的含义