2013-07-09 47 views
1

我想了解VS2012附帶的C++標準庫的xutility。就像VS一直附帶的所有版本的標準庫一樣,沒有一個是漂亮的。但有兩個聲明特別讓我完全陷入困境。即全局聲明的結構_Get_unchecked_type和_Is_checked_helper。VS2012 std庫xutility不可讀的實現

_Get_unchecked_type的實現看起來像這樣。

// file <xutility> 

     // TEMPLATE STRUCT _Get_unchecked_type 
template<class _Ty> 
    struct _Get_unchecked_type 
     _GET_TYPE_OR_DEFAULT(_Unchecked_type, 
      _Ty); 
// file <xtr1common> 

#define _GET_TYPE_OR_DEFAULT(TYPE, DEFAULT) \ 
    { \ 
    template<class _Uty> \ 
     static auto _Fn(int) \ 
      -> typename _Uty::TYPE; \ 
\ 
    template<class _Uty> \ 
     static auto _Fn(_Wrap_int) \ 
      -> DEFAULT; \ 
\ 
    typedef decltype(_Fn<_Ty>(0)) type; \ 
    } 

所以。 _Get_unchecked_type是一個結構體,其整個主體由xtr1common中定義的宏_GET_TYPE_OR_DEFAULT定義。

_GET_TYPE_OR_DEFAULT的第一個參數是_Unchecked_type,它似乎沒有在任何地方有意義的定義。鼠標懸停在_Unchecked_type彈出窗口告訴你,它是'typedef <錯誤類型> _Unchecked_type'這是沒有任何意義,因爲'<錯誤類型>'不是一個有效的類型。右鍵單擊_Unchecked_type並選擇'Go To Definition'將帶您進入_Array_const_iterator :: _ Unchecked_type的定義,這也不能正確,因爲struct _Get_unchecked_type在全局範圍內定義。

所以第一個問題是,什麼是_Unchecked_type,它在哪裏定義,以及您希望如何解決這個問題?

移至_GET_TYPE_OR_DEFAULT的定義。這個宏聲明瞭兩個稱爲_Fn的靜態成員函數模板重載。對於我的生活,我無法找到這些的定義。這些做什麼,它們在哪裏定義,你應該如何解決這個問題?

_Is_checked_helper的定義同樣是鈍的。

有人可以幫助我理解這些做什麼以及他們如何工作請。

回答

1

xutility是實現的一部分,並不是完全可讀的。它可能使用未定義的內部編譯器行爲。 _Unchecked_type是爲編譯器保留的名稱,對於我們所知的所有可以預定義的名稱如int

無論如何,這個定義成員type通過_Fn超載選擇。有兩種方法Fn,一種取int並返回Ty::TYPE,另一種取_Wrap_int並返回第二個宏參數DEFAULT。第一次轉換更好,但假定存在Ty::TYPE

因此,_Get_unchecked_type<A>::typeA::_Unchecked_type如果存在,並且只是A否則。

+0

非常感謝。在你的幫助下,我想我現在明白了。但它確實使我感到厭煩,儘管圖書館編寫者似乎沒有任何義務讓他們的代碼可讀,特別是對於像標準庫這樣的圖書館來說,這些圖書館可以擴展。我真的不知道如何將xutility視爲實現細節,因爲它包含許多核心迭代器聲明,如果您希望創建新的符合標準庫的容器,或者甚至只是新的迭代器專業化,則需要了解它們。 – Neutrino

+0

我認爲這裏的問題很大程度上在於C++本身,因爲對於模板代碼,它沒有提供將接口與實現分開的有效方法。我曾希望C++ 11能夠在這方面取得一些進展,但如果有什麼似乎越來越糟的話,這很奇怪,因爲在非模板代碼領域,C++支持的界面和實現代碼之間的分離度是像其他任何語言一樣好。 – Neutrino

+0

@Neutrino:C++當然是唯一擁有模板的主流語言。 Java和.Net專門定義了泛型,以避免C++在模板中出現的問題,結果是泛型會導致裝箱。另外,他們不能進行模板元編程。至於擴展,你根本不需要'xutility'。事實上,您現在可以在for循環中使用與STL兼容的容器,而不包含任何頭文件。 – MSalters