问题
I am looking into boost::swap implementation:
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);
}
}
The implementation also contains the following comment:
// 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.
However, I don't understand why primitive types (and why only primitive) cause infinite recursion.
回答1:
If swap_impl
is in the namespace boost
, the call swap(left,right);
in the implementation of swap_impl
will resolve to boost::swap
instead of std::swap
. That is, boost::swap -> boost::swap_impl -> boost::swap
, and thus infinite recursion.
As dyp has pointed out in the comment, the correct interpretation of the comment //use std::swap if argument dependent lookup fails
should be as follows: An unqualified swap(left,right)
is intended to select a specialized swapping function for the two arguments, found in the namespace of the types of those arguments. If such a specialized function has not been provided, the generic std::swap
is used as a fallback.
来源:https://stackoverflow.com/questions/30030925/why-move-swap-impl-in-boostswap-to-a-separate-namespace