当前位置:   article > 正文

C++ type_traits (tcy)

c++ type_traits
  1. 1.1.概述
  2. type_traits提供编译期间计算、查询、判断、转换和选择的帮助类
  3. 1.2.作用:
  4. 1)获取修改变量数据类型;获取函数返回类型;
  5. 2)判断数据类型,修改类型属性
  6. 3)重载相同参数不同的返回类型;
  7. 4)根据条件选择不同的数据类型;
  8. 5)编译器类型检查
  9. 1.3.定义:
  10. template <class T, T v>
  11. struct integral_constant {
  12. static constexpr T value = v;
  13. typedef T value_type;
  14. typedef integral_constant<T,v> type;
  15. constexpr operator T() { return v; }
  16. };
  17. 1.4.说明:
  18. 编译器匹配重载函数通常匹配所有重载函数,如匹配一个失败接着匹配其他重载函数,
  19. 选择最精确一个去执行,整个过程不会报错;除法都不匹配则报错。
  20. std::enable_if 根据条件选择重载函数,只对满足条件的函数有效。
  21. 可作用于返回值、模板定义、类模板特化、参数类型限定
  22. std::conditional根据条件返回不同类型
  1. 2.1.定义编译期常量方法:
  2. 1)定义静态变量:(C++11前)
  3. template<typename Type>
  4. struct CompileTimeContents{static const int value = 1;};
  5. 2)定义枚举变量:(C++11前)
  6. template<typename Type>
  7. struct CompileTimeContents{enum {value = 1};};
  8. 3)C++11中可通过std::integral_constant 模版类派生:
  9. template<typename Type>
  10. struct CompileTimeContents :std::integral_constant<int, 1> {};
  11. CompileTimeContents<type_name>::value;//获取该常量
  1. 2.2.判断类型:
  2. 1)判断数据类型:
  3. assert(is_const<const int>::value==true); //判断const类型
  4. assert(is_array<int[3]>::value==true); //判断是否为数组类型
  5. assert(is_array<int[](int x,int y)->int{return x+y}>::value==true);
  6. int add(int a, int b) { return a + b; }
  7. assert(is_function<int(int,int)>::value == true); //判断是否为函数类型
  8. assert(is_function<decltype(add)>::value == true);//lambda表达式不是函数
  9. int x = 0; int& r_x = x; //判断是否为引用类型
  10. assert(is_reference<int&>::value == true);
  11. assert(is_reference<decltype(r_x)>::value == true);
  1. 2)判断类型间关系:
  2. assert(is_same<int, int>::value==true); //判断类型是否相同
  3. assert(is_same<int, unsigned int>::value==false);
  4. struct A {};struct B : A {};
  5. assert(is_base_of<int,int>::value==false); //判断Base类型是否为Derivedl类型的基类
  6. assert(is_base_of<A,A>::value==true);
  7. assert(is_base_of<A,B>::value==true);
  8. assert(is_base_of<A,const A>::value==true);
  9. assert(is_base_of<A&,B&>::value==false);
  10. assert(is_base_of<B,A>::value==false);
  11. //is_convertible 判断前面模板参数类型能否转换为后面模板参数类型
  12. class A {};
  13. class B : public A {};
  14. class C {};
  15. class D { public: operator C() { return c; } C c; };
  16. class E { public: template<class T> E(T&&) { } };
  17. assert(is_convertible<B*, A*>::value==true);
  18. assert(is_convertible<A*, B*>::value==false);
  19. assert(is_convertible<B*, C*>::value==false);
  20. assert(is_convertible<D, C>::value==true);
  21. assert(is_convertible<A, E>::value==true); //< B, C, D, etc
  1. 2.3.根据条件选择类型
  2. //conditional在编译期根据条件选择两类型中的一个,类似常用条件表达式
  3. conditional<(true == true),int, char> ::type a;//等价int a;
  4. typedef std::conditional<true, int , char>::type A;
  1. 2.4.类型转换
  2. //对参数属性修改:cv属性添加或移除、引用添加或移除、数组维度修改
  3. typedef const volatile char cvchar;
  4. std::remove_cv<cvchar>::type a; // char a
  5. std::remove_cv<char* const>::type b; // char* b
  6. std::remove_cv<const char*>::type c; // const char* c (no changes)
  7. assert(is_const<decltype(a)>::value==false); // not const
  8. assert(is_volatile<decltype(a)>::value==false); // not volatile
  9. assert(is_same<const int, add_const<int>::type>::value==true); //添加const
  10. assert(is_same<int, remove_const<const int>::type>::value==true); //移除const
  11. assert(is_same<int&, add_lvalue_reference<int>::type>::value==true);//添加引用
  12. assert(is_same<int&&, add_rvalue_reference<int>::type>::value ==true);
  13. assert(is_same<int, int>::value==true);
  14. assert(is_same<int, int &>::value==false);
  15. assert(is_same<int, int &&>::value==false);
  16. assert(is_same<int, std::remove_reference<int>::type>==true); //移除引用
  17. assert(is_same<int, std::remove_reference<int &>::type==true);
  18. assert(is_same<int, std::remove_reference<int &&>::type==true);
  19. typedef common_type<unsigned char, short, int>::type NumericType; //取公共类型
  20. assert(is_same<int, NumericType>::value==true);
  1. 2.5.获取函数返回值类型
  2. //获取函数返回值类型使用decltype:T必须有构造函数
  3. template<typename T, typename Arg>
  4. auto Func(T a, Arg arg)->decltype(f(arg)){ return f(arg);}
  5. //类型没有模板参数或类型无构造函数,不能通过decltype来获取类型,用declval
  6. class A{A() = delete;public:int operator()(int i){return i;}};
  7. decltype(std::declval<A>()(std::declval<int>())) i = 4;//int i;
  8. //另一解决途径:std::result_of <traits>
  9. std::result_of<A(int)>::type i = 4; //C++20删除
  10. std::invoke_result<A,int>::type i=4; //C++17
  1. 2.6.type_traits std::decay(朽化)
  2. 用途:
  3. 利用std::decay可以方便的获得函数指针
  4. 说明:
  5. 对于普通类型移除引用和cv符(constvolatile),规则如下:
  6. 1)移除T类型的引用得到类型U,U为remove_reference < T > ::type
  7. 2)如is_array < U > ::value==true修改类型为 remove_reference< U >::type*
  8. 3)如is_function < U > ::value==true修改类型为add_pointer< U >::type
  9. 4)否则,修改类型为remove_cv< U >::type
  10. 实例:
  11. typedef std::decay<int>::type Normal; // int
  12. typedef std::decay<int&>::type Ref; // int
  13. typedef std::decay<int&&>::type RefRef; // int
  14. typedef std::decay<const int&>::type const; // int
  15. typedef std::decay<int[2]>::type Array; // int*
  16. typedef std::decay<int(int)>::type FunPtr; // int(*)(int) 函数指针
  1. 2.7.std::enable_if根据条件禁用或启用某些类型
  2. 用途:
  3. 利用SFINAE(substitude failuer is not an error)特性,根据条件选择重载函数
  4. 说明:
  5. enable_if 根据限定条件选择重载函数,只对满足条件的函数有效。
  6. 可作用于返回值、模板定义、类模板特化、参数类型限定
  1. 实例1.1:函数参数限定-T=int执行此函数,其他编译错误
  2. #include <iostream>
  3. #include <type_traits>
  4. using namespace std;
  5. template <class T>
  6. typename std::enable_if<std::is_integral<T>::value, bool>::type
  7. is_odd(T i) { return bool(i % 2); }
  1. 实例1.2:对模板参数限定-模板特化时模板参数只能是int类型
  2. template < class T,
  3. class = typename std::enable_if<std::is_integral<T>::value>::type>
  4. bool is_even(T i) { return !bool(i % 2); }
  5. // 通过编译期检查输入模板参数是否有效,来提前显示编译错误
  6. int main() {
  7. short int i = 1; // code does not compile if type of i is not integral
  8. std::cout << std::boolalpha;
  9. std::cout << "i is odd: " << is_odd(i) << std::endl;
  10. std::cout << "i is even: " << is_even(i) << std::endl;
  11. }
  1. 实例2.1:对函数返回值限定
  2. typename std::endable_if<std::is_arithmetic<T>::value, T>::type foo(T t)
  3. { return t;}
  4. auto numberic = foo(1); // 返回整数1
  5. auto str = foo("test"); // 编译失败
  1. 实例2.2:函数重载,通过enable_if和条件判断式,将入参分为两类(数字和非数字)
  2. template<class T>
  3. typename std::enable_if<std::is_arithmetic<T>::value, int>::type fool(T t)
  4. {
  5. cout<< t << endl;
  6. return 0;
  7. }
  8. template<class T>
  9. typename std::enable_if<!std::is_arithmetic<T>::value, int>::type fool(T& t) foo(T t)
  10. {
  11. cout << t << endl;
  12. return 1;
  13. }

3.简表

No函数说明
 true_typestd :: integer_constant < bool,true >具有指定值的指定类型的编译时常数 
 false_typestd::integral_constant<bool, false>
 Primary type categories主要类型类别 
1100is_void检查类型是否为 
1200is_null_pointer检查类型是否为std :: nullptr_t 
1320is_integral检查类型是否为整数类型 
1310is_floating_point检查类型是否为浮点类型(float,double) 
2300is_array检查类型是否为数组类型 
2500is_enum检查类型是否为枚举类型 
2620is_union检查类型是否为联合类型 
2610is_class检查类型是否为非联合类类型 
2400is_function检查类型是否为函数类型(labdda不是) 
2200is_pointer检查类型是否为指针类型 (包括函数指针,不包括成员函数指针)
2110is_lvalue_reference检查类型是否为左值引用 
2120is_rvalue_reference检查类型是否为右值引用 
2240is_member_object_pointer检查类型是否是指向非静态成员对象(类模板)的指针 
2250is_member_function_pointer检查类型是否是指向非静态成员函数(类模板)的指针 
 Composite type categories复合类型类别 
1000is_fundamental检查类型是否为基本类型 
1300is_arithmetic检查类型是否为算术类型 
 is_scalar检查类型是否为标量类型 (非数组或类)
 is_object检查类型是否为对象类型 (不是函数 不是引用 不是void)
2000is_compound检查类型是否为复合类型 
2100is_reference检查类型是左值引用还是右值引用 
2230is_member_pointer检查类型是否是指向非静态成员函数或对象(类模板)的指针 
 Type properties类型属性 
 is_const检查类型是否为const限定 
 is_volatile检查类型是否为volatile限定的 
 is_trivial检查类型是否是内置类型(有普通构造函数且含有成员变量)
 is_trivially_copyable检查类型是否可微复制 checks if a type is trivially copyable
 is_standard_layout检查类型是否为标准布局类型 
 is_pod检查类型是否为POD类型 (C++ 20中弃用)
1322is_literal_type检查类型是否为文字类型 (C ++ 20中删除)
 has_unique_object_representations检查类型的对象表示形式中的每一位是否有助于其值 
 is_empty检查类型是否为类(但不是联合)类型并且没有非静态数据成员 
 is_polymorphic检查类型是否为多态类类型 -虚函数
 is_abstract检查类型是否为抽象类类型 
 is_final检查类型是否为最终类类型final class 
 is_aggregate检查类型是否为聚合类型 
 is_signed检查类型是否为带符号算术类型 
 is_unsigned检查类型是否为无符号算术类型 
 is_bounded_array检查类型是否为已知绑定的数组类型(C ++ 20) 
 is_unbounded_array检查类型是否为未知界限的数组类型(C ++ 20) 
 is_scoped_enum检查类型是否为范围枚举类型(C ++ 23) 
 Supported operations支持的运营 
 is_constructible / is_trivially_constructible / is_nothrow_constructible检查类型是否具有用于特定参数的构造函数 
 is_default_constructible / is_trivially_default_constructible / is_nothrow_default_constructible检查类型是否具有默认构造函数 
 is_copy_constructible / is_trivially_copy_constructible / is_nothrow_copy_constructible检查类型是否具有复制构造函数 
 is_move_constructible / is_trivially_move_constructible / is_nothrow_move_constructible检查是否可以从右值引用(类模板)构造类型 
 is_assignable / is_trivially_assignable / is_nothrow_assignable检查类型是否具有用于特定参数的赋值运算符 
 is_copy_assignable / is_trivially_copy_assignable / is_nothrow_copy_assignable检查类型是否具有复制分配运算符 
 is_move_assignable / is_trivially_move_assignable / is_nothrow_move_assignable检查类型是否具有移动分配运算符 
 is_destructible / is_trivially_destructible / is_nothrow_destructible检查类型是否具有未删除的析构函数 
 has_virtual_destructor检查类型是否具有虚拟析构函数 
 is_swappable_with / is_swappable / is_nothrow_swappable_with / is_nothrow_swappable检查类型的对象是否可以与相同或不同类型的对象交换
 Property queries属性查询 
 alignment_of获取类型的对齐要求 
 rank获取数组类型的维数 
 extent获取沿指定维度的数组类型的大小 
 Type relationships类型关系 
 is_same检查两种类型是否相同 
 is_base_of检查一个类型是否从其他类型派生 
 is_convertibleis_nothrow_convertible检查一个类型是否可以转换为其他类型 
 is_layout_compatible检查两种类型是否与布局兼容(C ++ 20) 
 is_pointer_interconvertible_base_of检查一种类型是否是另一种类型的指针可互换(初始)基础(C ++ 20) 
 is_invocable / is_invocable_r / is_nothrow_invocable / is_nothrow_invocable_r检查是否可以使用给定的参数类型 (类模板)调用类型(就像通过std :: invoke一样
 Const-volatility specifiers常数波动指标 
 remove_cvremove_constremove_volatile从给定类型(类模板)中 删除const或/和volatile说明符 
 add_cvadd_constadd_volatileconst或/和volatile说明符添加到给定的类型 
 References参考文献 
 remove_reference从给定类型中删除引用 
 add_lvalue_reference/add_rvalue_reference向给定类型 添加左值或右值引用 
 Pointers指针 
 remove_pointer从给定类型中删除指针 
 add_pointer添加指向给定类型的指针 
 Sign modifiers标志修饰符 
 make_signed使给定的整数类型签名 
 make_unsigned使给定的整数类型无符号 
 Arrays数组 
 remove_extent移除数组顶层维度 
 remove_all_extents从给定的数组类型(类模板)中删除所有范围 
 Miscellaneous transformations杂项转换 
 aligned_storage定义适合用作给定大小的类型的未初始化存储的类型 
 aligned_union定义适用于所有给定类型的未初始化存储的类型 
 decay如通过值传递函数参数时应用类型转换 
 remove_cvref结合std :: remove_cvstd :: remove_reference (C ++ 20)
 enable_if隐藏基于编译时布尔值的函数重载或模板专门化 
 conditional根据编译时布尔值(类模板)选择一种或另一种类型 
 common_type确定一组类型的通用类型 
 underlying_type获取给定枚举类型的基础整数类型 
 result_ofinvoke_result推导带有一组参数的可调用对象的结果类型 (在C ++ 20中删除)
 void_t空可变参数别名模板 
 Operations on traits特征操作 
 conjunction可变逻辑AND功能 
 disjunction可变参数逻辑或元功能 
 negation逻辑非元功能 
 Functions 
 Member relationships会员关系 
 is_pointer_interconvertible_with_class检查类型的对象是否可以与该类型的指定子对象进行指针互换(C ++ 20) 
 is_corresponding_member检查两个指定类型(功能模板)公共初始子序列中两指定成员是否彼此对应(C++20)
 Constant evaluation context持续评估环境 
 is_constant_evaluated检测调用是否在常量求值的上下文(函数)中发生(C ++ 20) 
 remove_cv移除cv属性
 add_cv添加cv属性
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/310245
推荐阅读
相关标签
  

闽ICP备14008679号