为什么将 boost::swap 中的 swap_impl 移动到单独的命名空间?
why move swap_impl in boost::swap to a separate namespace?
我正在研究 boost::swap 实施:
namespace boost_swap_impl
{
template<class T>
BOOST_GPU_ENABLED
void swap_impl(T& left, T& right)
{
using namespace std;//use std::swap if argument dependent lookup fails
swap(left,right);
}
template<class T, std::size_t N>
BOOST_GPU_ENABLED
void swap_impl(T (& left)[N], T (& right)[N])
{
for (std::size_t i = 0; i < N; ++i)
{
::boost_swap_impl::swap_impl(left[i], right[i]);
}
}
}
namespace boost
{
template<class T1, class T2>
BOOST_GPU_ENABLED
void swap(T1& left, T2& right)
{
::boost_swap_impl::swap_impl(left, right);
}
}
实施还包含以下注释:
// Note: the implementation of this utility contains various workarounds:
// - swap_impl is put outside the boost namespace, to avoid infinite
// recursion (causing stack overflow) when swapping objects of a primitive
// type.
但是,我不明白为什么原始类型(以及为什么只有原始类型)会导致无限递归。
如果 swap_impl
在命名空间 boost
中,swap_impl
实现中的调用 swap(left,right);
将解析为 boost::swap
而不是 std::swap
.即boost::swap -> boost::swap_impl -> boost::swap
,从而无限递归。
正如 dyp 在评论中指出的那样,评论 //use std::swap if argument dependent lookup fails
的正确解释应该如下:一个不合格的 swap(left,right)
旨在 select 一个专门的交换函数这两个参数,在这些参数类型的命名空间中找到。如果没有提供这样的专门功能,则通用 std::swap
用作后备。
我正在研究 boost::swap 实施:
namespace boost_swap_impl
{
template<class T>
BOOST_GPU_ENABLED
void swap_impl(T& left, T& right)
{
using namespace std;//use std::swap if argument dependent lookup fails
swap(left,right);
}
template<class T, std::size_t N>
BOOST_GPU_ENABLED
void swap_impl(T (& left)[N], T (& right)[N])
{
for (std::size_t i = 0; i < N; ++i)
{
::boost_swap_impl::swap_impl(left[i], right[i]);
}
}
}
namespace boost
{
template<class T1, class T2>
BOOST_GPU_ENABLED
void swap(T1& left, T2& right)
{
::boost_swap_impl::swap_impl(left, right);
}
}
实施还包含以下注释:
// Note: the implementation of this utility contains various workarounds:
// - swap_impl is put outside the boost namespace, to avoid infinite
// recursion (causing stack overflow) when swapping objects of a primitive
// type.
但是,我不明白为什么原始类型(以及为什么只有原始类型)会导致无限递归。
如果 swap_impl
在命名空间 boost
中,swap_impl
实现中的调用 swap(left,right);
将解析为 boost::swap
而不是 std::swap
.即boost::swap -> boost::swap_impl -> boost::swap
,从而无限递归。
正如 dyp 在评论中指出的那样,评论 //use std::swap if argument dependent lookup fails
的正确解释应该如下:一个不合格的 swap(left,right)
旨在 select 一个专门的交换函数这两个参数,在这些参数类型的命名空间中找到。如果没有提供这样的专门功能,则通用 std::swap
用作后备。