C++ 标准库如何实现std::swap?

C++ 标准库如何实现std::swap?,c++,templates,swap,C++,Templates,Swap,如何在STL中实现交换功能?就这么简单吗? template<typename T> void swap(T& t1, T& t2) { T tmp(t1); t1=t2; t2=tmp; } 模板无效交换(T&t1、T&t2){ T-tmp(t1); t1=t2; t2=tmp; } 在其他帖子中,他们讨论了为自己的类专门化这个函数。我为什么要这么做?为什么我不能使用std::swap功能?如何实现std::swap? 是的,问题中给出的

如何在STL中实现交换功能?就这么简单吗?

template<typename T> void swap(T& t1, T& t2) {
    T tmp(t1);
    t1=t2;
    t2=tmp;
}
模板无效交换(T&t1、T&t2){
T-tmp(t1);
t1=t2;
t2=tmp;
}
在其他帖子中,他们讨论了为自己的类专门化这个函数。我为什么要这么做?为什么我不能使用
std::swap
功能?

如何实现
std::swap
? 是的,问题中给出的实现是经典的C++03实现

std::swap
的更现代(C++11)实现如下所示:

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);
}
模板无效交换(T&t1、T&t2){
T temp=std::move(t1);//或T temp(std::move(t1));
t1=std::move(t2);
t2=标准::移动(温度);
}
在资源管理方面,这是对经典C++03实现的改进,因为它防止了不必要的副本等。它,即C++11,要求类型
T
为and,从而允许实现和改进

为什么我需要提供自定义实现? 当您的实现比标准版本更高效或更具体时,通常建议针对特定类型的
交换的自定义实现

这方面的一个经典(C++11之前)示例是,当您的类管理大量资源时,复制和删除这些资源的成本很高。相反,您的自定义实现可以简单地交换实现交换所需的句柄或指针

随着
std::move
和movable类型(并实现您的类型)的出现,大约在C++11及以后,这里的许多原始原理开始消失;但是,如果定制掉期比标准掉期更好,那么就实施它

如果通用代码适当地使用了该机制,它通常能够使用您的自定义
交换

如何在STL中实现交换功能

哪种实现方式?这是一个规范,不是一个具体的库。如果您是指我的编译器的标准库是如何实现的,请告诉我们这是哪个编译器,或者自己阅读代码

就这么简单吗?

template<typename T> void swap(T& t1, T& t2) {
    T tmp(t1);
    t1=t2;
    t2=tmp;
}
这基本上是C++11之前的幼稚版本

这个非专门化的实现强制执行一个副本:在您的示例中,对于
T=std::vector
,代码翻译为:

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
请注意,这不涉及任何昂贵的拷贝,不涉及动态(取消)分配,并且保证不会抛出

现在,这种专门化的原因是vector::swap可以访问vector的内部,并且可以安全有效地在不复制的情况下移动它们

为什么我需要这样做[为你自己的班级专攻]

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);
}
模板无效交换(T&t1、T&t2){
温度=标准:移动(t1);
t1=std::move(t2);
t2=标准::移动(温度);
}

可以使用移动构造/分配来获得与上述自定义向量实现基本相同的行为,而无需编写自定义实现。

这正是
std::swap
在C++03中实现的方式,在C++11中是
T tmp(std::move(t1));t1=std::move(t2);t2=标准:移动(tmp)因为对于某些类型,这将比复制更有效。没有“标准库”。有一个,选择一个或几个,并查找它。@ NWP:每个实现都实现了“C++标准库”。参见〈171.1〉,但没有“STL”。标准库不是STL。@李斯特:这里完全是“STL”。它是由SGI编写的C++库,与C++标准库有着惊人的相似性。你能举一个例子,如果类实现了move构造函数,那么专门化swap仍然是有意义的吗?一个可能的原因是,如果设置moved from对象的状态不是很简单,并且没有在标准的
swap
实现中进行优化,然后,您可以编写一个比三步更有效的交换,不必费心设置。当然,这有很多“如果”,但是假设一个“从”移动的对象被定义为“空”,并且一个“空”对象包含一大堆零,可能还有一个虚拟节点结构。这是几篇文章,乘以三。所以通常可以忽略不计,但如果出现这种情况,您可能会为了性能而这样做。。。。另一方面,考虑类似字符串的字符串优化。当然,您可以实现move构造函数(传输长字符串的动态缓冲区),但也可以实现swap,以便(尝试)将短字符串缓冲区的内容交换到三个不同的内存区域,比将缓冲区内容的三个副本交换到三个不同的内存区域更有效。@ratchetfreak:我说的是然而,“尽可能最便宜的资源”比“零成本”更贵“。如果您的意思是“从状态移动”的成本应该为零,则可以,但尽管清除指针字段在几乎所有情况下实际上都是零成本,严格来说不是这样的。
swap
成员函数可以临时打破不变量,如果这样做比在每次移动后必须保持不变量的三次完整移动快的话。如果有一个有效的
X::swap(X&)
成员,那么专门化
swap(X&,X&)
来调用它是有意义的。一些移动操作甚至可以按照<代码>交换< /Cuth>成员实现,因此,一般的<代码> STD::SWIFT/CODEM>函数将调用<代码>交换< /C>成员三次,而只需要做一次。我使用VisualStudio 2005 C++(不支持C++ 11,但忽略)。如何访问源代码?我什么也找不到;可能是公共关系