why move swap_impl in boost::swap to a separate namespace?

吃可爱长大的小学妹 提交于 2019-12-22 13:53:02

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!