type_traits是元编程库的一部分,这个库主要用来判断数据类型,比如,判断类型是否为空,是否为空指针,是否为整型,是否为浮点型是否为数组,是否为枚举类型,是否为联合体,是否为函数,是否为指针,是否为左值引用,是否为右值引用,等等,判断的类型非常多,本篇介绍几个基本的。
| 基础类型分类 | |
| (C++11) | 检查类型是否为 void (类模板) |
| (C++14) | 检查类型是否为 std::nullptr_t (类模板) |
| (C++11) | 检查类型是否为整型 (类模板) |
| (C++11) | 检查类型是否是浮点类型 (类模板) |
| (C++11) | 检查类型是否是数组类型 (类模板) |
| (C++11) | 检查类型是否是枚举类型 (类模板) |
| (C++11) | 检查类型是否为联合体类型 (类模板) |
| (C++11) | 检查类型是否非联合类类型 (类模板) |
| (C++11) | 检查是否为函数类型 (类模板) |
| (C++11) | 检查类型是否为指针类型 (类模板) |
| (C++11) | 检查类型是否为左值引用 (类模板) |
| (C++11) | 检查类型是否为右值引用 (类模板) |
| (C++11) | 检查类型是否为指向非静态成员对象的指针 (类模板) |
| (C++11) | 检查类型是否为指向非静态成员函数的指针 (类模板) |
1. is_void 检查类型是否为 void
- #include
- #include
-
- using namespace std;
-
- int main()
- {
- cout << "std::is_void
::value==========" << std::is_void<void>::value << endl; - cout << "std::is_void
::value===========" << std::is_void<int>::value << endl; -
- cout << "Hello World!" << endl;
- return 0;
- }
运行结果:

2. is_null_pointer 检查类型是否为 std::nullptr_t
- #include
- #include
-
- using namespace std;
-
- int main()
- {
- cout << "std::is_null_pointer
::value = " << is_null_pointer<decltype(nullptr)>::value << endl; - cout << "std::is_null_pointer
::value = " << is_null_pointer<int*>::value << endl; -
- cout << "Hello World!" << endl;
- return 0;
- }
运行结果:

3. is_integral 检查类型是否为整型
- #include
- #include
-
- using namespace std;
-
- class A {};
-
- enum E: int {};
-
- template <class T>
- T fn(T i)
- {
- static_assert (std::is_integral
::value, "Integral required."); - return i;
- }
-
- int main()
- {
- cout << "std::is_integral::value======= " << std::is_integral::value << endl;
- cout << "std::is_integral
::value======= " << std::is_integral::value << endl; - cout << "std::is_integral
::value=== " << std::is_integral<float>::value << endl; - cout << "std::is_integral
::value===== " << std::is_integral<int>::value << endl; - cout << "std::is_integral
::value==== " << std::is_integral<bool>::value << endl; - cout << "fn(123)========================== " << fn(123) << endl;
- //cout << "fn(123.5)======================== " << fn(123.5) << endl; //编译失败
-
- cout << "Hello World!" << endl;
- return 0;
- }
运行结果:

4. is_floating_point 检查类型是否是浮点类型
- #include
- #include
-
- using namespace std;
-
- class A {};
-
- int main()
- {
- cout << "std::is_floating_point::value====== " << std::is_floating_point::value << endl;
- cout << "std::is_floating_point
::value== " << std::is_floating_point<float>::value << endl; - cout << "std::is_floating_point
::value== " << std::is_floating_point<float&>::value << endl; - cout << "std::is_floating_point
::value= " << std::is_floating_point<double>::value << endl; - cout << "std::is_floating_point
::value= " << std::is_floating_point<double&>::value << endl; - cout << "std::is_floating_point
::value==== " << std::is_floating_point<int>::value << endl; -
- cout << "Hello World!" << endl;
- return 0;
- }
运行结果:

5. is_array 检查类型是否是数组类型
- #include
- #include
-
- using namespace std;
-
- class A {};
-
- int main()
- {
- cout << "std::is_array::value============ " << std::is_array::value << endl;
- cout << "std::is_array::value========== " << std::is_array::value << endl;
- cout << "std::is_array::value========= " << std::is_array3]>::value << endl;
- cout << "std::is_array
::value======== " << std::is_array<float>::value << endl; - cout << "std::is_array
::value========== " << std::is_array<int>::value << endl; - cout << "std::is_array
::value======== " << std::is_array<int[]>::value << endl; - cout << "std::is_array
::value======= " << std::is_array<int[3]>::value << endl; - cout << "std::is_array
>::value= " << std::is_arrayint,3>>::value << endl; -
- cout << "Hello World!" << endl;
- return 0;
- }
运行结果:

6. is_enum 检查类型是否是枚举类型
- #include
- #include
-
- using namespace std;
-
- class A {};
-
- enum E {};
-
- enum class Ec: int {};
-
- int main()
- {
- cout << "std::is_enum::value====== " << std::is_enum::value << endl;
- cout << "std::is_enum
::value====== " << std::is_enum::value << endl; - cout << "std::is_enum
::value===== " << std::is_enum::value << endl; - cout << "std::is_enum
::value==== " << std::is_enum<int>::value << endl; -
- cout << "Hello World!" << endl;
- return 0;
- }
运行结果:

7. is_union 检查类型是否为联合体类型
- #include
- #include
-
- using namespace std;
-
- class A {};
-
- typedef union {
- int a;
- float b;
- } B;
-
- class C {
- B d;
- };
-
- int main()
- {
- cout << "std::is_union::value======== " << std::is_union::value << endl;
- cout << "std::is_union::value======== " << std::is_union::value << endl;
- cout << "std::is_union
::value======== " << std::is_union::value << endl; - cout << "std::is_union
::value====== " << std::is_union<int>::value << endl; -
- cout << "Hello World!" << endl;
- return 0;
- }
运行结果:

8. is_class 检查类型是否非联合类类型
- #include
- #include
-
- using namespace std;
-
- struct A { };
-
- class B { } ;
-
- enum class C { };
-
-
- int main()
- {
- cout << "std::is_class::value========== " << std::is_class::value << endl;
- cout << "std::is_class::value========== " << std::is_class::value << endl;
- cout << "std::is_class
::value========== " << std::is_class::value << endl; - cout << "std::is_class
::value======== " << std::is_class<int>::value << endl; -
- cout << "Hello World!" << endl;
- return 0;
- }
运行结果:

9. is_function 检查是否为函数类型
- #include
- #include
-
- using namespace std;
-
- struct A {
- int fun() const &;
- };
-
- template<typename>
- struct PM_traits { };
-
- template<class T, class U>
- struct PM_traits {
- using member_type = U;
- };
-
- int f();
-
- int main()
- {
- cout << "std::is_function::value================= " << std::is_function::value << endl;
- cout << "std::is_function
::value========== " << std::is_function<int(int)>::value << endl; - cout << "std::is_function
::value======= " << std::is_function<decltype(f)>::value << endl; - cout << "std::is_function
::value=============== " << std::is_function<int>::value << endl; - using T = PM_traits<decltype(&A::fun)>::member_type; //T为int() const&
- cout << "std::is_function
::value================= " << std::is_function::value << endl; -
- cout << "Hello World!" << endl;
- return 0;
- }
运行结果:

10. is_pointer 检查类型是否为指针类型
- #include
- #include
-
- using namespace std;
-
- struct A {
- int fun() const &;
- };
-
- int main()
- {
- cout << "std::is_pointer::value ================= " << is_pointer::value << endl;
- cout << "std::is_pointer::value =============== " << is_pointer::value << endl;
- cout << "std::is_pointer::value =============== " << is_pointer::value << endl;
- cout << "std::is_pointer
::value =============== " << is_pointer<int>::value << endl; - cout << "std::is_pointer
::value ============= " << is_pointer<int *>::value << endl; - cout << "std::is_pointer
::value ============ " << is_pointer<int **>::value << endl; - cout << "std::is_pointer
::value =========== " << is_pointer<int[10]>::value << endl; - cout << "std::is_pointer
::value ========= " << is_pointer<nullptr_t>::value << endl; - cout << "std::is_pointer
::value = " << is_pointer<decltype(nullptr)>::value << endl; -
- cout << "Hello World!" << endl;
- return 0;
- }
运行结果:

11. is_lvalue_reference 检查类型是否为左值引用
- #include
- #include
-
- using namespace std;
-
- class A { };
-
- int main()
- {
- cout << "std::is_lvalue_reference::value====== " << std::is_lvalue_reference::value << endl;
- cout << "std::is_lvalue_reference::value===== " << std::is_lvalue_reference::value << endl;
- cout << "std::is_lvalue_reference::value==== " << std::is_lvalue_reference::value << endl;
- cout << "std::is_lvalue_reference
::value==== " << std::is_lvalue_reference<int>::value << endl; - cout << "std::is_lvalue_reference
::value=== " << std::is_lvalue_reference<int&>::value << endl; - cout << "std::is_lvalue_reference
::value== " << std::is_lvalue_reference<int&&>::value << endl; -
- cout << "Hello World!" << endl;
- return 0;
- }
运行结果:

12. is_rvalue_reference 检查类型是否为右值引用
- #include
- #include
-
- using namespace std;
-
- class A { };
-
- int main()
- {
- cout << "std::is_rvalue_reference::value====== " << std::is_rvalue_reference::value << endl;
- cout << "std::is_rvalue_reference::value===== " << std::is_rvalue_reference::value << endl;
- cout << "std::is_rvalue_reference::value==== " << std::is_rvalue_reference::value << endl;
- cout << "std::is_rvalue_reference
::value==== " << std::is_rvalue_reference<int>::value << endl; - cout << "std::is_rvalue_reference
::value=== " << std::is_rvalue_reference<int&>::value << endl; - cout << "std::is_rvalue_reference
::value== " << std::is_rvalue_reference<int&&>::value << endl; -
- cout << "Hello World!" << endl;
- return 0;
- }
运行结果:

13. is_member_object_pointer 检查类型是否为指向非静态成员对象的指针
- #include
- #include
-
- using namespace std;
-
- int main()
- {
- class cls {};
- std::cout << (std::is_member_object_pointer<int(cls::*)>::value
- ? "T is member object pointer"
- : "T is not a member object pointer") << endl;
- std::cout << (std::is_member_object_pointer<int(cls::*)()>::value
- ? "T is member object pointer"
- : "T is not a member object pointer") << endl;
-
- cout << "Hello World!" << endl;
- return 0;
- }
运行结果:

14. is_member_function_pointer 检查类型是否为指向非静态成员函数的指针
- #include
- #include
-
- using namespace std;
-
- class A {
- public:
- void member() { }
- };
-
- int main()
- {
- // 若 A::member 是数据成员而非函数,则在编译时失败
- static_assert(std::is_member_function_pointer<decltype(&A::member)>::value,
- "A::member is not a member function.");
-
- cout << "Hello World!" << endl;
- return 0;
- }
参考: