2015-05-04 13 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

相關問題