### 如何重载std :: swap（）

`std::vector`

#### 4 个答案:

``````class X
{
// ...
friend void swap(X& a, X& b)
{
using std::swap; // bring in swap for built-in types

swap(a.base1, b.base1);
swap(a.base2, b.base2);
// ...
swap(a.member1, b.member1);
swap(a.member2, b.member2);
// ...
}
};
``````

``````// simulate <algorithm>

#include <cstdio>

namespace exp
{

template <class T>
void
swap(T& x, T& y)
{
printf("generic exp::swap\n");
T tmp = x;
x = y;
y = tmp;
}

template <class T>
void algorithm(T* begin, T* end)
{
if (end-begin >= 2)
exp::swap(begin[0], begin[1]);
}

}

// simulate user code which includes <algorithm>

struct A
{
};

namespace exp
{
void swap(A&, A&)
{
printf("exp::swap(A, A)\n");
}

}

// exercise simulation

int main()
{
A a[2];
exp::algorithm(a, a+2);
}
``````

``````generic exp::swap
``````

``````// simulate <algorithm>

#include <cstdio>

namespace exp
{

template <class T>
void
swap(T& x, T& y)
{
printf("generic exp::swap\n");
T tmp = x;
x = y;
y = tmp;
}

template <class T>
void algorithm(T* begin, T* end)
{
if (end-begin >= 2)
swap(begin[0], begin[1]);
}

}

// simulate user code which includes <algorithm>

struct A
{
};

void swap(A&, A&)
{
printf("swap(A, A)\n");
}

// exercise simulation

int main()
{
A a[2];
exp::algorithm(a, a+2);
}
``````

``````swap(A, A)
``````

<强>更新

``````namespace exp
{
template <>
void swap(A&, A&)
{
printf("exp::swap(A, A)\n");
}

}
``````

``````// simulate user code which includes <algorithm>

template <class T>
struct A
{
};

namespace exp
{

template <class T>
void swap(A<T>&, A<T>&)
{
printf("exp::swap(A, A)\n");
}

}

// exercise simulation

int main()
{
A<int> a[2];
exp::algorithm(a, a+2);
}
``````

``````namespace std
{
template<>
void swap(my_type& lhs, my_type& rhs)
{
// ... blah
}
}
``````

``````class Base
{
// ... stuff ...
}
class Derived : public Base
{
// ... stuff ...
}

namespace std
{
template<>
void swap(Base& lha, Base& rhs)
{
// ...
}
}
``````

17.4.3.1/1     对于C ++程序来说，添加声明或定义是未定义的     除非另有说明，否则使用命名空间std来命名std或命名空间     指定。程序可以为任何程序添加模板特化     标准库模板到命名空间std。这样的专业化     （完整或部分）标准库导致未定义     行为，除非声明取决于用户定义的名称     外部链接，除非模板专业化符合     原始模板的标准库要求。

std :: swap的特殊化看起来像：

``````namespace std
{
template<>
void swap(myspace::mytype& a, myspace::mytype& b) { ... }
}
``````