2015-05-04 38 views
2

我期待到的boost ::交换的实现:为什么将boost :: swap中的swap_impl移动到单独的命名空间?

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. 

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

+0

命名空间最有可能是ADL障碍。但我现在没有心情/没有时间去进一步解释 – sehe

+0

@Puppy,boost重新实现它,所以你不需要在swap(a,b)之前使用std :: swap编写每次您无法通过ADL获得更有效的实施时,都会回到std :: swap。 –

+0

@AntonFrolov真正的问题是为什么'std :: swap'没有以这种方式实现。 – Lingxi

回答

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用作回退。

+0

这是我最初的想法,然而,有两件事让我感到困惑:1)为什么只有原始类型才会发生无限递归; 2)为什么它会解决boost :: swap?编译器应该在:: std和:: boost中看到swap实现,并且由于模糊调用而发出错误。 –

+0

1)我想作家真的试图意味着没有重载'std :: swap'的类型。原始类型是其中之一。 2)这由函数调用解析规则来管理。我对规则的细节并不熟悉,因此无法就此给出准确答案。抱歉。 – Lingxi

+0

http://stackoverflow.com/questions/30032332/confustions-around-function-call-resolution。这个问题应该可以帮助我们两个人:-) – Lingxi

相关问题