有关boost :: swap的问题

时间:2011-05-24 18:39:19

标签: c++ boost

关于boost::swap的几个问题。请参考下面的代码,该代码基本上是boost/swap.hpp的剪切粘贴。我指的是库版本1.43.0。

namespace boost_swap_impl
    {
      template<class T>
      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>
  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>
  void swap(T1& left, T2& right)
  {
    ::boost_swap_impl::swap_impl(left, right);
  }
}
  1. 为什么boost::swap声明为template <typename T1, typename T2>,在其余代码中它们都处理相同的类型?
  2. 如果我定义自己的全局函数void swap(T&, T&),我看到它是从swap_impl(T& left, T& right)调用的全局函数。这不是冲突,因此是一个错误条件,因为swap_impl也使用已定义交换的namespace std吗?

1 个答案:

答案 0 :(得分:19)

  1. 这使得它不如std::swap专业化,因此当std::swapboost::swap都在范围内时(std::swap优先),您不会出现过载歧义错误。
  2. 不,非模板在重载解析期间始终优先于模板,因此命名空间范围的非模板swap将优先于boost::swapstd::swap(因为命名空间范围的模板swap为UDT重载 - 认为部分专用,但不是真的...)。请注意,与std::swap不同,boost::swap是明确编写的,以利用ADL
  3. 以下是关于这两点的C ++ 03标准所说的内容 - [over.match.best](§13.3.3/ 1):

      

    按如下方式定义ICS i F):

         
        
    • 如果F是静态成员函数,则定义ICS 1 F),使得ICS 1 F )对于任何函数G,并且对称地,ICS 1 ({{1} })既不比ICS 1 G)更好也不差;否则,
    •   
    • 让ICS i G)表示隐式转换序列,它将列表中的 i -th参数转换为的类型i - 可行函数F的第i个参数。 13.3.3.1定义了隐式转换序列,13.3.3.2定义了一个隐式转换序列比另一个转换序列更好的转换序列或更差转换序列的含义。
    •   
         

    鉴于这些定义,如果对于所有参数 i ,可行函数F被定义为更好函数而不是另一个可行函数F。 ,ICS i F1)转换序列不比ICS i F2)差,然后

         
        
    • 对于某些参数 j ,ICS j F1)是比ICS j 更好的转换序列({{1 }}),或者,如果不是那样,
    •   
    • F2是非模板函数,F1是函数模板特化,或者,如果不是,
    •   
    • F2F1是函数模板特化,F2的函数模板比​​F1的模板更专业,根据14.5中描述的部分排序规则.5.2,或者,如果不是,
    •   
    • 上下文是由用户定义的转换初始化(参见8.5,13.3.1.5和13.3.1.6)以及从F2的返回类型到目标类型的标准转换序列(即类型正在初始化的实体)是一个比返回类型F1到目标类型的标准转换序列更好的转换序列。
    •