为什么将swap_impl在boost :: swap中移动到单独的命名空间? [英] why move swap_impl in boost::swap to a separate namespace?

查看:204
本文介绍了为什么将swap_impl在boost :: swap中移动到单独的命名空间?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找boost :: swap实现:

 命名空间boost_swap_impl 
{
template<类T>
BOOST_GPU_ENABLED
void swap_impl(T& left,T& right)
{
using namespace std; //如果参数依赖查找失败,使用std :: swap
swap (左右);
}

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 {
:: boost_swap_impl :: swap_impl(left [i],right [i]);
}
}
}

命名空间boost
{
template< class T1,class T2>
BOOST_GPU_ENABLED
void swap(T1& left,T2& right)
{
:: boost_swap_impl :: swap_impl(left,right);
}
}

实现还包含以下注释:

  //注意:此实用程序的实现包含各种解决方法:
// - swap_impl放在boost命名空间外,避免无限的
//当交换原语
//类型的对象时递归(导致堆栈溢出)。但是,我不明白为什么原始类型(以及为什么只有原始类型)会导致无限递归。 / p>

解决方案

如果 swap_impl 位于命名空间 boost ,在 swap_impl 的实现中调用 swap(左,右); boost :: swap 而不是 std :: swap 。也就是说, boost :: swap - > boost :: swap_impl - > boost :: swap ,因此无限递归。



由于dyp在注释中指出,注释的正确解释 //使用std :: swap如果参数依赖查找失败应如下所示:未限定交换(左,右)为这两个参数选择一个专门的交换函数,在这些参数的类型的命名空间中找到。如果没有提供这样的特殊函数,则使用通用 std :: swap 作为后备。


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.

解决方案

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.

这篇关于为什么将swap_impl在boost :: swap中移动到单独的命名空间?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆