在理解type_traits类型判断的时候,看到网上关于is_base_of的源码,自己C++水平有限,特别是模版,对其中的实现一直不理解。
以下记录个人思考的过程,方便自己或他人。
is_base_of 作用是 判断 Base 是否为 Derived 的基类。
其中的主要源码如下:
template<typename Base, typename Devied, bool = (is_class<Base>::value && is_class<Devied>::value)>
class is_base_of
{
template<typename T>
static char helper(Devied, T);
static int helper(Base, int);
struct Conv
{
operator Devied();
operator Base() const;
};
public:
static const bool value = sizeof(helper(Conv(), 0) == 1);
};
template<typename Base, typename Derived>
class is_base_of<Base, Derived, false>
{
public:
static const bool value = is_same<Base, Derived>::value;
};
其中关于type_traits类型判断 请参考这个链接,里面有详细的实现。
-
is_class
是type_traits中判断是否是类类型的函数模板,详细参考type_traits类型判断; -
operator Devied()
是类型转换操作符,将类类型值转变为其他类型值的转换,在保留字 operator 之后跟着转换的目标类型,详细参考类型强制转换成员函数; -
重点分析
value = sizeof(helper(Conv(), 0) == 1)
-
当
Base
不是Devied
的超类时,那 operator Devied() 和 operator Base() const 则不是重载关系了;接下来,两个函数类型转换函数都可以匹配 helper(Conv(), 0) ,因为 operator Devied() 满足 static char helper(Devied, T); operator Base() const 满足 static int helper(Base, int);但是由于优先匹配非模板的函数的规则,在这里会匹配 static int helper(Base, int);Conv()
会转换成Base
,helper(Conv(), 0)
返回的类型是int
,最后 sizeof(int) != 1 。 -
当
Base
是Devied
的超类时,那 operator Devied() 和 operator Base() const 则是重载 关系。那由于 Conv() 不是const
类型,只能调用 operator Devied() 做类型转换,最后只能匹配 static char helper(Devied, T); 返回的类型是char
,最后 sizeof(char) == 1 。
网友评论