判断是否是enum类型,且不能转化为int类型。(enum class的实现。强类型匹配,不能隐士转化)
template <bool _First_value, class _First, class... _Rest>
struct _Conjunction { // handle false trait or last trait
using type = _First;
};
template <class _True, class _Next, class... _Rest>
struct _Conjunction<true, _True, _Next, _Rest...> { // the first trait is true, try the next one
using type = typename _Conjunction<_Next::value, _Next, _Rest...>::type;
};
template <class... _Traits>
struct conjunction : true_type {}; // If _Traits is empty, true_type
template <class _First, class... _Rest>
struct conjunction<_First, _Rest...> : _Conjunction<_First::value, _First, _Rest...>::type {
// the first false trait in _Traits, or the last trait if none are false
};
template <class... _Traits>
_INLINE_VAR constexpr bool conjunction_v = conjunction<_Traits...>::value;
//可变参数中有false则为false,没有或全部正确则为true。详细解析见其他文章。
#if _HAS_CXX23
template <class _Ty>
inline constexpr bool is_scoped_enum_v = conjunction_v<is_enum<_Ty>, negation<is_convertible<_Ty, int>>>;
//is_enum<_Ty>判断是不是枚举类型。is_convertible<_Ty, int>判断_Ty能够隐士转化为int。negation<is_convertible<_Ty, int>>对最后的结果取反。
//最后得到要想为返回值为true,必须是枚举类型且不能隐士转化为int类型。
template <class _Ty>
struct is_scoped_enum : bool_constant<is_scoped_enum_v<_Ty>> {};
//重新定义一个结构体继承bool_constant,便于在模板里使用。
#endif // _HAS_CXX23
判断是不是自定义类型,不是基础类型(整形,浮点型,void, nullptr)
template <class _Ty>
_INLINE_VAR constexpr bool is_fundamental_v = is_arithmetic_v<_Ty> || is_void_v<_Ty> || is_null_pointer_v<_Ty>;
//判断是不是基础类型 (is_arithmetic_v<_Ty>判断是不是整形数据,is_void_v<_Ty>判断是不是void类型,is_null_pointer_v<_Ty>判断是不是空)
template <class _Ty>
struct is_compound : bool_constant<!is_fundamental_v<_Ty>> {}; // determine whether _Ty is a compound type
//不是基础类型则是true_type,是基础类型则false_type;
template <class _Ty>
_INLINE_VAR constexpr bool is_compound_v = !is_fundamental_v<_Ty>;
//不是基础类型则是true,是基础类型则false;
判断是不是类内函数
template <class... _Types>
struct _Arg_types {}; // provide argument_type, etc. when sizeof...(_Types) is 1 or 2
template <class _Ty1>
struct _Arg_types<_Ty1> {
_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty1 _ARGUMENT_TYPE_NAME;
};
template <class _Ty1, class _Ty2>
struct _Arg_types<_Ty1, _Ty2> {
_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty1 _FIRST_ARGUMENT_TYPE_NAME;
_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty2 _SECOND_ARGUMENT_TYPE_NAME;
};
template <class _Ty>
struct _Is_memfunptr { // base class for member function pointer predicates
using _Bool_type = false_type; // NB: members are user-visible via _Weak_types
};
#define _IS_MEMFUNPTR(CALL_OPT, CV_OPT, REF_OPT, NOEXCEPT_OPT) \
template <class _Ret, class _Arg0, class... _Types> \
struct _Is_memfunptr<_Ret (CALL_OPT _Arg0::*)(_Types...) CV_OPT REF_OPT NOEXCEPT_OPT> \
: _Arg_types<CV_OPT _Arg0*, _Types...> { \
using _Bool_type = true_type; \
_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ret _RESULT_TYPE_NAME; \
using _Class_type = _Arg0; \
using _Guide_type = enable_if<!is_same_v<int REF_OPT, int&&>, _Ret(_Types...)>; \
};
_MEMBER_CALL_CV_REF_NOEXCEPT(_IS_MEMFUNPTR)
#undef _IS_MEMFUNPTR
#define _IS_MEMFUNPTR_ELLIPSIS(CV_REF_NOEXCEPT_OPT) \
template <class _Ret, class _Arg0, class... _Types> \
struct _Is_memfunptr<_Ret (_Arg0::*)(_Types..., ...) \
CV_REF_NOEXCEPT_OPT> { /* no calling conventions for ellipsis */ \
using _Bool_type = true_type; \
_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ret _RESULT_TYPE_NAME; \
using _Class_type = _Arg0; \
using _Guide_type = enable_if<false>; \
};
_CLASS_DEFINE_CV_REF_NOEXCEPT(_IS_MEMFUNPTR_ELLIPSIS)
#undef _IS_MEMFUNPTR_ELLIPSIS
#ifdef __clang__
template <class _Ty>
_INLINE_VAR constexpr bool is_member_function_pointer_v = __is_member_function_pointer(_Ty);
#else // ^^^ Clang ^^^ / vvv Other vvv
template <class _Ty>
_INLINE_VAR constexpr bool is_member_function_pointer_v = _Is_memfunptr<remove_cv_t<_Ty>>::_Bool_type::value;
#endif // ^^^ Other ^^^
函数可以加引用属性
#include <iostream>
struct test {
void fun()& { std::cout << "左值函数" << std::endl; }
void fun()&& { std::cout << "右值函数" << std::endl; }
};
int main() {
test t;
t.fun();
test().fun();
}