Max*_*dig 58 c++ templates swap
如何在STL中实现交换功能?它是这么简单:
template<typename T> void swap(T& t1, T& t2) {
T tmp(t1);
t1=t2;
t2=tmp;
}
Run Code Online (Sandbox Code Playgroud)
在其他帖子中,他们谈论为您自己的班级专门化这个功能.我为什么要这样做?为什么我不能使用这个std::swap功能?
Nia*_*all 57
std::swap实施?是的,问题中提出的实现是经典的C++ 03.
一个更现代(C++ 11)的实现std::swap看起来像这样:
template<typename T> void swap(T& t1, T& t2) {
T temp = std::move(t1); // or T temp(std::move(t1));
t1 = std::move(t2);
t2 = std::move(temp);
}
Run Code Online (Sandbox Code Playgroud)
这是对资源管理方面的经典C++ 03实现的改进,因为它可以防止不需要的副本等.它,C++ 11 std::swap,要求类型T为MoveConstructible和MoveAssignable,从而允许实现和改进.
swap当您的实现比标准版本更高效或特定时,通常会建议针对特定类型的自定义实现.
一个典型的例子就是当你的类管理大量资源时,复制然后删除会很昂贵.相反,您的自定义实现可以简单地交换实现交换所需的句柄或指针.
随着std::move可移动类型的出现(并且实现了你的类型),大约在C++ 11及之后,这里的许多原始理由开始消失; 但是,如果自定义交换比标准交换更好,则实现它.
swap如果适当地使用ADL机制,通用代码通常可以使用您的自定义.
Use*_*ess 18
如何在STL中实现交换功能?
哪个实施?这是一个规范,而不是一个单独的具体库.如果您的意思是我的编译器的标准库如何做,请告诉我们是哪个编译器,或者自己阅读代码.
它是这么简单:
这基本上是C++ 11之前的天真版本.
这种非专业化的实现会强制复制:T = std::vector<SomethingExpensive>在您的示例中,代码转换为:
template<typename T> void swap(T& t1, T& t2) {
T tmp(t1); // duplicate t1, making an expensive copy of each element
t1=t2; // discard the original contents of t1,
// and replace them with an expensive duplicate of t2
t2=tmp; // discard the original contents of t2,
// and replace them with an expensive duplicate of tmp
} // implicitly destroy the expensive temporary copy of t1
Run Code Online (Sandbox Code Playgroud)
所以交换我们从根本上创造两个向量3.有三个动态分配和许多昂贵的对象被复制,并且任何这些操作都可能抛出,可能使参数处于不确定状态.
由于这显然很糟糕,为昂贵的容器提供了重载,并且鼓励您为自己的昂贵类型编写重载:例如.在std::vector专业化已经进入向量机的内部,并且可以交换两个向量没有所有的复制:
template <typename T> void swap(vector<T> &v1, vector<T> &v2) { v1.swap(v2); }
template <typename T> void vector<T>::swap(vector<T>& other) {
swap(this->size_, other.size_); // cheap integer swap of allocated count
swap(this->used_, other.used_); // cheap integer swap of used count
swap(this->data__, other.data_); // cheap pointer swap of data ptr
}
Run Code Online (Sandbox Code Playgroud)
请注意,这不涉及任何昂贵的任何副本,没有动态(de)分配,并且保证不会抛出.
现在,这种专业化的原因是vector :: swap可以访问vector的内部结构,并且可以安全有效地移动它们而无需复制.
为什么我需要这样做[专门为你自己的班级]?
Pre-C++ 11,出于同样的原因std::vector- 使交换高效且异常安全.
从C++ 11开始,你真的没有 - 如果你提供移动构造和赋值,或者编译器可以为你生成合理的默认值.
新的通用交换:
template <typename T> void swap(T& t1, T& t2) {
T temp = std::move(t1);
t1 = std::move(t2);
t2 = std::move(temp);
}
Run Code Online (Sandbox Code Playgroud)
可以使用移动构造/赋值来获得与上面的自定义向量实现基本相同的行为,而无需编写自定义实现.
| 归档时间: |
|
| 查看次数: |
24858 次 |
| 最近记录: |