2015-12-29 112 views
2

我試圖瞭解從模板類enable_shared_from_this弱指針成員(使用Visual Studio 2013 C++編譯器)如何基於特定的派生類

mutable weak_ptr<_Ty> _Wptr 

如何被初始化調用方法時std::shared_ptr<_Ty>是從它派生的對象中創建的。爲此我跟蹤從與模板函數std::make_share<_Ty>

我發現_Wptr初始化進行時調用基類_Ref_count_del_alloc內的方法_Enable_shared編譯器創建一個std::shared_ptr<_Ty>一個簡單的代碼。

現在爲此目的定義了2個模板方法。當_Ty類從enable_shared_from_this派生時定義了一種方法。這是該方法:

template<class _Ty> 
inline void _Enable_shared(_Ty *_Ptr, _Ref_count_base *_Refptr, 
    typename _Ty::_EStype * = 0) 
{ // reset internal weak pointer 
if (_Ptr) 
    _Do_enable(_Ptr, 
     (enable_shared_from_this<typename _Ty::_EStype>*)_Ptr, _Refptr); 
} 

_Ty不是來自enable_shared_from_this衍生第二種方法被定義。這是方法:

inline void _Enable_shared(const volatile void *, const volatile void *) 
{ 
    // not derived from enable_shared_from_this; do nothing 
} 

我有的問題是如何C++編譯器能夠解決使用哪種方法?除此之外,我希望這兩種方法都可以在編譯時實例化,並且如果類不是從enable_shared_from_this派生的,則會出現編譯錯誤。然而,編譯器似乎只選擇一種方法來實例化和適當的方法。

+3

什麼你快意恩仇叫「法」實際上是一個*函數模板*。可以定義未實例化的模板。功能模板專門化可能不適合選擇推導出的參數,因此不參與重載解析(「sfinae」)。 –

+1

理解指針初始化方式的更好方法是自己實現enable_shared工具。看着別人無法解釋的代碼,你就會陷入任意細節。 –

回答

1

在挖掘代碼之後,我發現理解這個過程的關鍵是通過Kerry SB指出的函數模板特化。由於_EStype僅在enable_shared_from_this基本模板類中定義,因此編譯器能夠根據來自參數的格式不正確的調用在_Enable_shared函數模板中進行選擇。

這在香草薩特的下面的帖子很好的解釋:

Why Not Specialize Function Templates?

+1

這不是真正的功能模板專業化;它實際上是[SFINAE]的應用程序(https://en.wikipedia.org/wiki/Substitution_failure_is_not_an_error)。 – Angew

+0

感謝您指出並提供鏈接到SFINAE。這正是代碼所做的。良好的聯繫和解釋 –