说在前面,试图从头开始看明白C++标准库的构成。
1.true_type,false_type
template <class _Ty, _Ty _Val>
struct integral_constant {
static constexpr _Ty value = _Val;
using value_type = _Ty;
using type = integral_constant;
constexpr operator value_type() const noexcept {
return value;
}
[[nodiscard]] constexpr value_type operator()() const noexcept {
return value;
}
};
template <bool _Val>
using bool_constant = integral_constant<bool, _Val>;
using true_type = bool_constant<true>;
using false_type = bool_constant<false>;
(1) 记住有叫integral_constant和 bool_constant的东西。
(2)::value是bool值。
2. enable_if
template <bool _Test, class _Ty = void>
struct enable_if {};
template <class _Ty>
struct enable_if<true, _Ty> {
using type = _Ty;
};
template <bool _Test, class _Ty = void>
using enable_if_t = typename enable_if<_Test, _Ty>::type;
过!
3. conditional
template <bool _Test, class _Ty1, class _Ty2>
struct conditional {
using type = _Ty1;
};
template <class _Ty1, class _Ty2>
struct conditional<false, _Ty1, _Ty2> {
using type = _Ty2;
};
template <bool _Test, class _Ty1, class _Ty2>
using conditional_t = typename conditional<_Test, _Ty1, _Ty2>::type;
(1) conditional使用bool值判断,而不是bool_type判断。
(2)不怎么常看见,容易忘。
4. is_same
template <class, class>
inline constexpr bool is_same_v = false;
template <class _Ty>
inline constexpr bool is_same_v<_Ty, _Ty> = true;
template <class _Ty1, class _Ty2>
struct is_same : bool_constant<is_same_v<_Ty1, _Ty2>> {};
过!
5.remove_cv
template <class _Ty>
struct remove_const {
using type = _Ty;
};
template <class _Ty>
struct remove_const<const _Ty> {
using type = _Ty;
};
template <class _Ty>
using remove_const_t = typename remove_const<_Ty>::type;
template <class _Ty>
struct remove_volatile {
using type = _Ty;
};
template <class _Ty>
struct remove_volatile<volatile _Ty> {
using type = _Ty;
};
template <class _Ty>
using remove_volatile_t = typename remove_volatile<_Ty>::type;
template <class _Ty>
struct remove_cv {
using type = _Ty;
};
template <class _Ty>
struct remove_cv<const _Ty> {
using type = _Ty;
};
template <class _Ty>
struct remove_cv<volatile _Ty> {
using type = _Ty;
};
template <class _Ty>
struct remove_cv<const volatile _Ty> {
using type = _Ty;
};
template <class _Ty>
using remove_cv_t = typename remove_cv<_Ty>::type;
过!
6.disjunction
template <bool _First_value, class _First, class... _Rest>
struct _Disjunction {
using type = _First;
};
template <class _False, class _Next, class... _Rest>
struct _Disjunction<false, _False, _Next, _Rest...> {
using type = typename _Disjunction<_Next::value, _Next, _Rest...>::type;
};
template <class... _Traits>
struct disjunction : false_type {};
template <class _First, class... _Rest>
struct disjunction<_First, _Rest...> :
_Disjunction<_First::value, _First, _Rest...>::type {};
template <class... _Traits>
inline constexpr bool disjunction_v = disjunction<_Traits...>::value;
(1)_Disjunction实现很巧妙。
(2)但是_Disjunction需要第一个bool值手动写出来,通过 disjunction包装来解决这个问题。
(3)disjunction是0连续||每个bool_type,而不是bool值。
7.is_integral,is_floating_point,is_arithmetic
template <class _Ty, class... _Types>
inline constexpr bool _Is_any_of_v = disjunction_v<is_same<_Ty, _Types>...>;
template <class _Ty>
inline constexpr bool is_integral_v = _Is_any_of_v<remove_cv_t<_Ty>,
bool, char, signed char, unsigned char, wchar_t, char8_t, char16_t, char32_t,
short, unsigned short, int, unsigned int, long, unsigned long, long long,
unsigned long long>;
template <class _Ty>
struct is_integral : bool_constant<is_integral_v<_Ty>> {};
template <class _Ty>
inline constexpr bool is_floating_point_v = _Is_any_of_v<remove_cv_t<_Ty>,
float, double, long double>;
template <class _Ty>
struct is_floating_point : bool_constant<is_floating_point_v<_Ty>> {};
template <class _Ty>
inline constexpr bool is_arithmetic_v = is_integral_v<_Ty> || is_floating_point_v<_Ty>;
template <class _Ty>
struct is_arithmetic : bool_constant<is_arithmetic_v<_Ty>> {};
很多问题不是解决不了,只是懒不想,穷举罢了 。
8.remove_reference
template <class _Ty>
struct remove_reference {
using type = _Ty;
};
template <class _Ty>
struct remove_reference<_Ty&> {
using type = _Ty;
};
template <class _Ty>
struct remove_reference<_Ty&&> {
using type = _Ty;
};
template <class _Ty>
using remove_reference_t = typename remove_reference<_Ty>::type;
template <class _Ty>
struct remove_cvref {
using type = remove_cvref_t<_Ty>;
};
到此结束,下一篇笔记再见。