如何基于特定的派生类调用方法 我试图理解弱指针成员(使用Visual Studio 2013 C++编译器)

如何基于特定的派生类调用方法 我试图理解弱指针成员(使用Visual Studio 2013 C++编译器),c++,templates,c++11,C++,Templates,C++11,第二种方法是在\Ty类不是从中派生的从该中启用共享时定义的。方法如下: 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_fr

第二种方法是在
\Ty
不是从
中派生的
从该
中启用共享时定义的。方法如下:

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);
}
inline void _Enable_shared(const volatile void *, const volatile void *)
{   
    // not derived from enable_shared_from_this; do nothing
}

我的问题是C++编译器是如何解决使用哪种方法的?此外,如果类不是从
enable\u shared\u from\u this
派生的,我希望这两个方法都在编译时实例化,并且会出现编译错误。然而,编译器似乎只选择了一个实例化方法和合适的方法。

在深入研究代码后,我发现理解如何实现这一点的关键是通过Kerry SB指出的函数模板专门化。由于
\u EStype
仅在该
基模板类中的
启用共享\u启用共享
函数模板之间进行选择

赫伯·萨特(Herb Sutter)的以下帖子对此有很好的解释:


您草率地称之为“方法”的实际上是一个函数模板。可以定义未实例化的模板。对于推导参数的选择来说,函数模板专门化的形式可能不正确,但不会参与重载解析(“sfinae”)。了解指针如何初始化的更好方法是自己实现一个enable_共享工具。看着别人无法解释的代码,你只会陷入任意的细节中。这不是真正的函数模板专业化;这实际上是的一个应用程序。感谢您指出这一点,并提供指向SFINAE的链接。代码就是这样做的。好的链接和解释
inline void _Enable_shared(const volatile void *, const volatile void *)
{   
    // not derived from enable_shared_from_this; do nothing
}