首页 文章

为什么要将boost :: swap中的swap_impl移动到一个单独的命名空间?

提问于
浏览
2

我正在研究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.

但是,我不明白为什么原始类型(以及为什么只有原语)会导致无限递归 .

1 回答

  • 2

    如果 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) 旨在为这两个参数选择一个专用的交换函数,这些参数位于这些参数类型的命名空间中 . 如果未提供此类专用功能,则通用 std::swap 将用作后备 .

相关问题