假设我有这样的课程:
struct A{
  std::string a;
  std::string b;
  std::string c;
  std::string d;
};
如果我使用std::swap,它可能会做这样的事情:
// pseudo-code:
void std::swap(A &a, A &b){
   A tmp = std::move(a);
   a = std::move(b);
   b = std::move(tmp);
}
它将tmp使用默认的c-tor 构建"空"对象- 通常是廉价的操作.然后它有望移动3次,除了疯狂的情况下移动衰变复制.
但是,如果我自己交换:
void swap(A &a, A &b){
   std::swap(a.a, b.a);
   std::swap(a.b, b.b);
   std::swap(a.c, b.c);
   std::swap(a.d, b.d);
}
它肯定会使用更少的内存,但它仍然需要构造空std::string-  4次!
我可以疯狂,用单身做std::string.
在所有情况下,它看起来都不是很大的改进.
只有适当的情况我能想到的是,如果默认的c-tor是非常昂贵的.我对么?
好吧,你不能说你需要或永远不应该自己制作swap,这完全取决于上下文。在您的示例中,它很可能是不必要的,但您的类的逻辑可能更复杂。
假设您有一个类,它保存指向某个数据结构的指针,以及与该结构关联的许多指标,每个指标都需要很长时间来计算,并且需要大量空间来存储,并且这些指标被用作对数据进行一些计算时的临时变量(我知道下面的示例可能是一个设计蹩脚的类,但它应该说明这个想法):
class MyClass
{
public:
   void doSomeWork()
   {
       //uses _metricsOneValue and _metricsTwoValue as temporaries,
       //calls other functions that use them as temporaries too, etc.
   }
private:
   //used only in doSomeWork and functions called by it.
   //Value overwritten each call.
   SomeBigClass _metricsOneValue; 
   SomeBigClass _metricsTwoValue;
   <...>
   SomeOtherClass * _data;
}
现在假设您需要swap()该类的两个实例。最直接的实现将复制包括旧指标在内的所有内容,实际上目前不需要这些指标,因为doSomeWork()无论如何它们都会在您下次调用时被覆盖。因此,在这种情况下,您可以swap通过仅交换数据结构的指针来优化。