参考下面一句静态断言:
static_assert(!std::is_same<bool, T>::value, "vector<bool> is abandoned in mystl");
静态断言优点:可以自定义断言失败之后的输出 便于debug找问题
其中我们用到了std::is_same
点进is_same进行源码分析:
template<typename, typename> struct is_same : public false_type { }; template<typename _Tp> struct is_same<_Tp, _Tp> : public true_type { };
可以看出两种is_same分别继承于两个不同的结构体
再来看看false_type和true_type的定义:
typedef integral_constant<bool, true> true_type; typedef integral_constant<bool, false> false_type;
可以看出这两个来自于同一个结构体模版:integral_constant
继续看integral_constant的定义:
template<typename _Tp, _Tp __v> struct integral_constant { static constexpr _Tp value = __v; typedef _Tp value_type; typedef integral_constant<_Tp, __v> type; constexpr operator value_type() const noexcept { return value; } #if __cplusplus > 201103L #define __cpp_lib_integral_constant_callable 201304 constexpr value_type operator()() const noexcept { return value; } #endif };
下面的宏定义不用管
可以看出这个模版需要一个_Tp类 然后还需要一个非模版类型的参数_v 并且这个参数的类型和_Tp的类型相同 并且会把这个非模版类型参数_v赋值给结构体成员变量
记得我们最开始调用is_same时
static_assert(!std::is_same<bool, T>::value, "vector<bool> is abandoned in mystl");
原来断言的就是这个value的值(一定是个bool且必须是个bool)
回到上一步false_type和true_type的定义:
typedef integral_constant<bool, true> true_type; typedef integral_constant<bool, false> false_type;
可以看出实际上是起了两个别名 true_type结构体中包含的value成员变量一定是true flase_type结构体中包含的value成员变量一定是false 我们需要断言的也就是这个value的值 再往回导一步:
template<typename, typename> struct is_same : public false_type { }; template<typename _Tp> struct is_same<_Tp, _Tp> : public true_type { };
这个是模版调用优先级的问题 实际上 当传入相同类型的参数时(std::is_same<bool, bool>)此时会直接调用下面的is_same 反之如果两个类型不同 则会调用上面的is_same
所以最开始我们的调用:
static_assert(!std::is_same<bool, T>::value, "vector<bool> is abandoned in mystl");
这里的实际要求是不能传入bool类型的变量 即vector不接受bool类型
这设计思路真的很棒