背景
对于这个问题,请考虑以下代码:
#include <utility>
namespace ns
{
struct foo
{
foo() : i(0) {}
int i;
private:
foo(const foo&); // not defined,
foo& operator=(const foo&); // non-copyable
};
void swap(foo& lhs, foo& rhs)
{
std::swap(lhs.i, rhs.i);
}
}
template <typename T>
void do_swap(T& lhs, T& rhs); // implementation to be determined
int main()
{
ns::foo a, b;
do_swap(a, b);
}
在 C++03 中,这个实现do_swap
将被认为是“损坏的”:
template <typename T>
void do_swap(T& lhs, T& rhs)
{
std::swap(lhs, rhs);
}
通过显式指定std::
,它禁止ns::swap
通过依赖于参数的查找找到。(然后编译失败,因为std::swap
试图复制 a foo
,这是不允许的。)相反,我们这样做:
template <typename T>
void do_swap(T& lhs, T& rhs)
{
using std::swap; // allow std::swap as a backup if ADL fails to find a swap
swap(lhs, rhs); // unqualified call to swap, allow ADL to operate
}
Nowns::swap
被发现std::swap
,并且由于不那么专业,所以不使用。它更丑陋,但它有效并且事后看来是可以理解的。boost::swap
为我们很好地包装了这个(并提供了数组重载):
#include <boost/swap.hpp>
template <typename T>
void do_swap(T& lhs, T& rhs)
{
boost::swap(lhs, rhs); // internally does what do_swap did above
}
问题
因此,我的问题是:是否具有C++11 中std::swap
的行为?boost::swap
如果不是,为什么?
对我来说,这似乎很明显。任何被更改破坏的代码一开始都可能非常脆弱(算法和容器,如std::sort
and std::vector
,未指定;允许实现调用 ADL 交换或不确定地调用),因此更改会更好。另外,std::swap
现在是为数组定义的,所以改变肯定不是不可能的。
然而,虽然 §17.6.3.2 规定swap
标准库中的所有调用都必须在没有std::
限定的情况下完成(解决上述算法和容器的问题),但它并没有涉及到std::swap
自身。它甚至给出了交换值的示例,包括using std::swap;
. 同样,第 20.2.2 节(在哪里std::swap
指定)没有对 ADL 说一句话。
最后,GCC 并没有在他们的std::swap
实现中启用 ADL(MSVC 也没有,但这没什么好说的)。所以我一定是错的,std::swap
采取的行为boost::swap
,但我不明白为什么没有做出改变。:(而且我并不孤单!