在这个关于复制和交换的question中,接受的答案中有一个swap()函数。
friend void swap(dumb_array& first, dumb_array& second) // nothrow
{
// enable ADL (not necessary in our case, but good practice)
using std::swap;
// by swapping the members of two classes,
// the two classes are effectively swapped
swap(first.mSize, second.mSize);
swap(first.mArray, second.mArray);
}
为什么不只是std::swap(first, second)
?
答案 0 :(得分:7)
std::swap
依赖于赋值运算符。因此,如果赋值运算符要调用std::swap
,这将导致赋值运算符与std::swap
之间来回的无限调用。
关于标题中的问题。是的,对于具有值语义的行为良好的类,可以安全地在该类的对象上调用std::swap
。由于上述原因,只有该类的实施者不能将其用于复制和交换习语。
答案 1 :(得分:1)
C ++ 98建议使用代码片段,在同一个答案中还有另一个C ++ 11(移动语义)的建议。
Scott Meyers的Effective C ++书中很好地解释了为C ++ 98解决方案提供swap()
函数的原因。
简言之;
template<typename T> // typical implementation of std::swap;
void swap(T& a, T& b) // swaps a's and b's values
{
T temp(a);
a = b;
b = temp;
}
只要您的类型支持复制(通过复制构造函数和复制 赋值运算符),默认的交换实现会让对象 您的类型将被交换,而无需您进行任何特殊工作 支持它。
但是,默认的交换实现可能不会让您感到兴奋。它 涉及复制三个对象:a到temp,b到a,temp到b。对于 某些类型,这些副本都不是必需的。对于这种类型, 默认交换使您快速通往慢车道。
这些类型中最重要的是主要由指针组成的类型 到另一种包含真实数据的类型。一种常见的表现形式 这种设计方法是“pimpl成语”......