赞
踩
- 1.1.概述
- type_traits提供编译期间计算、查询、判断、转换和选择的帮助类
-
- 1.2.作用:
- 1)获取修改变量数据类型;获取函数返回类型;
- 2)判断数据类型,修改类型属性
- 3)重载相同参数不同的返回类型;
- 4)根据条件选择不同的数据类型;
- 5)编译器类型检查
-
- 1.3.定义:
- template <class T, T v>
- struct integral_constant {
- static constexpr T value = v;
- typedef T value_type;
- typedef integral_constant<T,v> type;
- constexpr operator T() { return v; }
- };
-
- 1.4.说明:
- 编译器匹配重载函数通常匹配所有重载函数,如匹配一个失败接着匹配其他重载函数,
- 选择最精确一个去执行,整个过程不会报错;除法都不匹配则报错。
-
- std::enable_if 根据条件选择重载函数,只对满足条件的函数有效。
- 可作用于返回值、模板定义、类模板特化、参数类型限定
-
- std::conditional根据条件返回不同类型

- 2.1.定义编译期常量方法:
- 1)定义静态变量:(C++11前)
- template<typename Type>
- struct CompileTimeContents{static const int value = 1;};
-
- 2)定义枚举变量:(C++11前)
- template<typename Type>
- struct CompileTimeContents{enum {value = 1};};
-
- 3)C++11中可通过std::integral_constant 模版类派生:
- template<typename Type>
- struct CompileTimeContents :std::integral_constant<int, 1> {};
-
- CompileTimeContents<type_name>::value;//获取该常量
- 2.2.判断类型:
-
- 1)判断数据类型:
- assert(is_const<const int>::value==true); //判断const类型
-
- assert(is_array<int[3]>::value==true); //判断是否为数组类型
- assert(is_array<int[](int x,int y)->int{return x+y}>::value==true);
-
- int add(int a, int b) { return a + b; }
- assert(is_function<int(int,int)>::value == true); //判断是否为函数类型
- assert(is_function<decltype(add)>::value == true);//lambda表达式不是函数
-
- int x = 0; int& r_x = x; //判断是否为引用类型
- assert(is_reference<int&>::value == true);
- assert(is_reference<decltype(r_x)>::value == true);
- 2)判断类型间关系:
- assert(is_same<int, int>::value==true); //判断类型是否相同
- assert(is_same<int, unsigned int>::value==false);
-
- struct A {};struct B : A {};
-
- assert(is_base_of<int,int>::value==false); //判断Base类型是否为Derivedl类型的基类
- assert(is_base_of<A,A>::value==true);
- assert(is_base_of<A,B>::value==true);
- assert(is_base_of<A,const A>::value==true);
- assert(is_base_of<A&,B&>::value==false);
- assert(is_base_of<B,A>::value==false);
-
- //is_convertible 判断前面模板参数类型能否转换为后面模板参数类型
- class A {};
- class B : public A {};
- class C {};
- class D { public: operator C() { return c; } C c; };
- class E { public: template<class T> E(T&&) { } };
-
- assert(is_convertible<B*, A*>::value==true);
- assert(is_convertible<A*, B*>::value==false);
- assert(is_convertible<B*, C*>::value==false);
- assert(is_convertible<D, C>::value==true);
- assert(is_convertible<A, E>::value==true); //< B, C, D, etc

- 2.3.根据条件选择类型
- //conditional在编译期根据条件选择两类型中的一个,类似常用条件表达式
- conditional<(true == true),int, char> ::type a;//等价int a;
- typedef std::conditional<true, int , char>::type A;
- 2.4.类型转换
- //对参数属性修改:cv属性添加或移除、引用添加或移除、数组维度修改
- typedef const volatile char cvchar;
- std::remove_cv<cvchar>::type a; // char a
- std::remove_cv<char* const>::type b; // char* b
- std::remove_cv<const char*>::type c; // const char* c (no changes)
-
- assert(is_const<decltype(a)>::value==false); // not const
- assert(is_volatile<decltype(a)>::value==false); // not volatile
-
- assert(is_same<const int, add_const<int>::type>::value==true); //添加const
- assert(is_same<int, remove_const<const int>::type>::value==true); //移除const
-
- assert(is_same<int&, add_lvalue_reference<int>::type>::value==true);//添加引用
- assert(is_same<int&&, add_rvalue_reference<int>::type>::value ==true);
-
- assert(is_same<int, int>::value==true);
- assert(is_same<int, int &>::value==false);
- assert(is_same<int, int &&>::value==false);
-
- assert(is_same<int, std::remove_reference<int>::type>==true); //移除引用
- assert(is_same<int, std::remove_reference<int &>::type==true);
- assert(is_same<int, std::remove_reference<int &&>::type==true);
-
- typedef common_type<unsigned char, short, int>::type NumericType; //取公共类型
- assert(is_same<int, NumericType>::value==true);

- 2.5.获取函数返回值类型
-
- //获取函数返回值类型使用decltype:T必须有构造函数
- template<typename T, typename Arg>
- auto Func(T a, Arg arg)->decltype(f(arg)){ return f(arg);}
-
- //类型没有模板参数或类型无构造函数,不能通过decltype来获取类型,用declval
- class A{A() = delete;public:int operator()(int i){return i;}};
- decltype(std::declval<A>()(std::declval<int>())) i = 4;//int i;
-
- //另一解决途径:std::result_of <traits>
- std::result_of<A(int)>::type i = 4; //C++20删除
- std::invoke_result<A,int>::type i=4; //C++17
- 2.6.type_traits std::decay(朽化)
- 用途:
- 利用std::decay可以方便的获得函数指针
-
- 说明:
- 对于普通类型移除引用和cv符(const和volatile),规则如下:
- 1)移除T类型的引用得到类型U,U为remove_reference < T > ::type
- 2)如is_array < U > ::value==true修改类型为 remove_reference< U >::type*
- 3)如is_function < U > ::value==true修改类型为add_pointer< U >::type
- 4)否则,修改类型为remove_cv< U >::type
-
- 实例:
- typedef std::decay<int>::type Normal; // int
- typedef std::decay<int&>::type Ref; // int
- typedef std::decay<int&&>::type RefRef; // int
- typedef std::decay<const int&>::type const; // int
- typedef std::decay<int[2]>::type Array; // int*
- typedef std::decay<int(int)>::type FunPtr; // int(*)(int) 函数指针

- 2.7.std::enable_if根据条件禁用或启用某些类型
- 用途:
- 利用SFINAE(substitude failuer is not an error)特性,根据条件选择重载函数
-
- 说明:
- enable_if 根据限定条件选择重载函数,只对满足条件的函数有效。
- 可作用于返回值、模板定义、类模板特化、参数类型限定
- 实例1.1:函数参数限定-T=int执行此函数,其他编译错误
- #include <iostream>
- #include <type_traits>
-
- using namespace std;
-
- template <class T>
- typename std::enable_if<std::is_integral<T>::value, bool>::type
- is_odd(T i) { return bool(i % 2); }
- 实例1.2:对模板参数限定-模板特化时模板参数只能是int类型
- template < class T,
- class = typename std::enable_if<std::is_integral<T>::value>::type>
- bool is_even(T i) { return !bool(i % 2); }
-
- // 通过编译期检查输入模板参数是否有效,来提前显示编译错误
- int main() {
- short int i = 1; // code does not compile if type of i is not integral
-
- std::cout << std::boolalpha;
- std::cout << "i is odd: " << is_odd(i) << std::endl;
- std::cout << "i is even: " << is_even(i) << std::endl;
- }
- 实例2.1:对函数返回值限定
- typename std::endable_if<std::is_arithmetic<T>::value, T>::type foo(T t)
- { return t;}
-
- auto numberic = foo(1); // 返回整数1
- auto str = foo("test"); // 编译失败
- 实例2.2:函数重载,通过enable_if和条件判断式,将入参分为两类(数字和非数字)
- template<class T>
- typename std::enable_if<std::is_arithmetic<T>::value, int>::type fool(T t)
- {
- cout<< t << endl;
- return 0;
- }
-
- template<class T>
- typename std::enable_if<!std::is_arithmetic<T>::value, int>::type fool(T& t) foo(T t)
- {
- cout << t << endl;
- return 1;
- }
3.简表
No | 函数 | 说明 |
true_type | std :: integer_constant < bool,true >具有指定值的指定类型的编译时常数 | |
false_type | std::integral_constant<bool, false> | |
Primary type categories主要类型类别 | ||
1100 | is_void | 检查类型是否为空 |
1200 | is_null_pointer | 检查类型是否为std :: nullptr_t |
1320 | is_integral | 检查类型是否为整数类型 |
1310 | is_floating_point | 检查类型是否为浮点类型(float,double) |
2300 | is_array | 检查类型是否为数组类型 |
2500 | is_enum | 检查类型是否为枚举类型 |
2620 | is_union | 检查类型是否为联合类型 |
2610 | is_class | 检查类型是否为非联合类类型 |
2400 | is_function | 检查类型是否为函数类型(labdda不是) |
2200 | is_pointer | 检查类型是否为指针类型 (包括函数指针,不包括成员函数指针) |
2110 | is_lvalue_reference | 检查类型是否为左值引用 |
2120 | is_rvalue_reference | 检查类型是否为右值引用 |
2240 | is_member_object_pointer | 检查类型是否是指向非静态成员对象(类模板)的指针 |
2250 | is_member_function_pointer | 检查类型是否是指向非静态成员函数(类模板)的指针 |
Composite type categories复合类型类别 | ||
1000 | is_fundamental | 检查类型是否为基本类型 |
1300 | is_arithmetic | 检查类型是否为算术类型 |
is_scalar | 检查类型是否为标量类型 (非数组或类) | |
is_object | 检查类型是否为对象类型 (不是函数 不是引用 不是void) | |
2000 | is_compound | 检查类型是否为复合类型 |
2100 | is_reference | 检查类型是左值引用还是右值引用 |
2230 | is_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中弃用) | |
1322 | is_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_volatile | 将const或/和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_cv和std :: 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属性 |
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。