基于pp. 8
免费功能
template<typename T> void swap(scoped_ptr<T>& a,scoped_ptr<T>& b)
此功能提供了交换的首选方式 两个范围指针的内容。因为这是优选的 swap(scoped1,scoped2)可以一般地应用(在模板化代码中) 许多指针类型,包括原始指针和第三方智能 指针。[2] scoped1.swap(scoped2)仅适用于智能指针,而不适用 在原始指针上,并且仅在那些定义操作的指针上。
int* pA = new int(10);
int *pB = new int(20);
boost::swap(pA, pB); // Error: could not deduce template argument for 'boost::scoped_ptr<T> &' from 'int *'
问题&GT;如何用boost::swap
交换原始指针?
答案 0 :(得分:5)
这归结为交换习惯用法,或者用户代码应该如何实现交换。对于具有一组成员swap
... T
的名称空间N
中的m1
类型实施mN
的推荐方法是:
namespace N {
void swap( T& lhs, T& rhs ) {
using std::swap;
swap( lhs.m1, rhs.m1 );
...
swap( lhs.mN, rhs.mN );
}
}
这个成语利用了ADL(Argument Dependent Lookup)。它首先将std::swap
的定义注入范围,以便在交换特定元素时不存在更好的重载时可用。然后使用非限定的自由函数swap
,知道如果任何Tn
成员的类型mn
定义了自由函数交换,ADL将把它带入范围和将使用专门的swap
而不是std::swap
。
文档说的是,您不应该调用ptr1.swap( ptr2 )
,而是不合格 swap( ptr1, ptr2 )
来交换任何元素,包括{{1对象,遵循上面的习语。也就是说,如果你实现你的交换,scoped_ptr
函数不需要因为你的成员类型的变化而改变,包括指针只是一个原始指针还是swap
。
答案 1 :(得分:4)
我不明白为什么其他答案告诉你不要使用boost::swap
。 boost::swap
的完整目的是隐藏using std::swap; swap(x, y);
业务。这很好用:
#include <boost/swap.hpp>
int main()
{
int* pA = new int(10);
int *pB = new int(20);
boost::swap(pA, pB);
delete pA;
delete pB;
}
显然,如果你没有包含boost/swap.hpp
,这将无效。这就是你使用boost::swap
交换两件事的方法。你应该总是喜欢用这种形式交换两件东西!
您正在阅读的内容只是说明boost::scoped_ptr
还在swap
命名空间中提供了boost
的重载,因此这也适用:
#include <boost/scoped_ptr.hpp>
int main()
{
boost::scoped_ptr<int> pA(new int(20));
boost::scoped_ptr<int> pB(new int(20));
boost::swap(pA, pB);
}
但应该清楚的是,这不起作用:
#include <boost/scoped_ptr.hpp>
int main()
{
int* pA = new int(10);
int *pB = new int(20);
boost::swap(pA, pB);
delete pA;
delete pB;
}
因为boost/scoped_ptr.hpp
没有提供(实际上没有责任提供)boost::swap
的一般实现。如果您想一般使用boost::swap
,则必须包含boost/swap.hpp
:
#include <boost/scoped_ptr.hpp>
#include <boost/swap.hpp>
int main()
{
int* pA = new int(10);
int *pB = new int(20);
boost::scoped_ptr<int> pC(new int(20));
boost::scoped_ptr<int> pD(new int(20));
boost::swap(pA, pB);
boost::swap(pC, pD);
delete pA;
delete pB;
}
像那样。如果您可以使用Boost,请不要回到使用std::swap
的东西。