C++ Type Traits

Type Traits 是 C++11 中的一种模板元编程技术,它提供了一系列的模板类和函数,用于在编译时查询和操作类型信息。这些类型特征可以用于泛型编程中,帮助我们编写更加灵活、通用和安全的代码。

例如:判断一个类型是否为指针类型、是否为整数类型、是否可以进行拷贝构造等等。这使得我们可以根据类型的属性来做出不同的编译时决策,从而避免在运行时出现错误或者不必要的性能损失。

1. 基本类型

#if 0
#include <iostream>
#include <type_traits>
using namespace std;

class MyClass {};

void i(){}


void test()
{
	int a = 100;
	double b = 3.14;
	int* c = nullptr;
	int& d = a;
	int&& e = 200;
	enum MyEnum{} f;
	union MyUnion {} g;
	MyClass h;


	cout << "int a = 100;" << endl;
	cout << "double b = 3.14;" << endl;
	cout << "int* c = nullptr;" << endl;
	cout << "int& d = a;" << endl;
	cout << "int&& e = 200;" << endl;
	cout << "enum MyEnum{} f;" << endl;
	cout << "union MyUnion {} g;" << endl;
	cout << "MyClass h;" << endl;
	cout << "void i(){}" << endl;
	cout << endl;


	// bool, char, signed char, unsigned char, wchar_t, char16_t, char32_t, short, int, long, long long
	cout << "是否整数:" << endl;
	cout << "a\t" << is_integral<decltype(a)>::value << endl;
	
	// float, double, long double
	cout << "是否浮点数:" << endl;
	cout << "b\t" << is_floating_point<decltype(b)>::value << endl;

	cout << "是否指针:" << endl;
	cout << "c\t" << is_pointer<decltype(c)>::value << endl;

	cout << "是否空指针:" << endl;
	cout << "c\t" << is_null_pointer<decltype(c)>::value << endl;

	cout << "是否引用:" << endl;
	cout << "d\t" << is_reference<decltype(d)>::value << endl;
	cout << "e\t" << is_reference<decltype(e)>::value << endl;

	cout << "是否左值引用:" << endl;
	cout << "d\t" << is_lvalue_reference<decltype(d)>::value << endl;

	cout << "是否右值引用:" << endl;
	cout << "e\t" << is_rvalue_reference<decltype(e)>::value << endl;

	cout << "是否枚举:" << endl;
	cout << "f\t" << is_enum<decltype(f)>::value << endl;

	cout << "是否联合体:" << endl;
	cout << "g\t" << is_union<decltype(g)>::value << endl;

	cout << "是否类:" << endl;
	cout << "h\t" << is_class<decltype(h)>::value << endl;

	cout << "是否函数:" << endl;
	cout << "i\t" << is_function<decltype(i)>::value << endl;
}

int main()
{
	test();
	return 0;
}


#endif

2. CV 限定符

#if 0
#include <iostream>
#include <type_traits>
using namespace std;

void test()
{	

	const int a = 10;
	const int* b = nullptr;
	int* const c = nullptr;
	// 引用的对象是 cons int
	const int& d = a;
	// 引用的对象是 const int&& 
	const int&& e = 10;

	cout << "是否 const:" << endl;
	cout << "a\t" << is_const<decltype(a)>::value << endl;
	cout << "b\t" << is_const<decltype(b)>::value << endl;
	cout << "c\t" << is_const<decltype(c)>::value << endl;
	cout << "d\t" << is_const<decltype(d)>::value << endl;
	cout << "e\t" << is_const<decltype(e)>::value << endl;

	
	volatile int f = 10;
	volatile int* g = nullptr;
	int* volatile h = nullptr;

	cout << "是否 volatile:" << endl;
	cout << "f\t" << is_volatile<decltype(f)>::value << endl;
	cout << "g\t" << is_volatile<decltype(g)>::value << endl;
	cout << "h\t" << is_volatile<decltype(h)>::value << endl;
}

int main()
{
	test();
	return 0;
}


#endif

3. 关系判断

#if 0
#include <iostream>
#include <type_traits>
using namespace std;

class Base {};
class Derived : public Base {};

void test()
{

	Base base1, base2;
	Derived s1, s2;

	cout << "是否同类型:" << endl;
	cout << "p1 p2\t" << is_same<decltype(base1), decltype(base2)>::value << endl;
	cout << "p1 Person\t" << is_same<decltype(base1), Base>::value << endl;

	cout << "是否是基类:" << endl;
	cout << "Base 是 Derived 基类\t" << is_base_of<Base, Derived>::value << endl;


	// 判断一个类型是否可以隐式转换为另一个类型。
	cout << "是否可以转换类型:" << endl;
	cout << "Base 转换 Derived 类型\t" << is_convertible<Base, Derived>::value << endl;
	cout << "Derived 转换 Base 类型\t" << is_convertible<Derived, Base>::value << endl;
	cout << "double* 转换 int 类型\t" << is_convertible<double*, int>::value << endl;
	cout << "int 转换 double* 类型\t" << is_convertible<int, double*>::value << endl;
}

int main()
{
	test();
	return 0;
}


#endif

4. 修饰符

#if 1
#include <iostream>
#include <type_traits>
using namespace std;

template<class T>
struct RemomveAllPointers 
{
	using type = T;
};


template<class T>
struct RemomveAllPointers<T*>
{
	using type = typename RemomveAllPointers<T>::type;
};


// 1. 移除修饰符
void test01()
{

	const int a = 10;
	volatile int b = 20;

	int temp = 10;
	int& c = temp;
	int&& d = 10;

	int* e = nullptr;
	int** f = nullptr;

	cout << "移除 const:" << endl;
	cout << typeid(remove_const<decltype(a)>::type).name() << endl;

	cout << "移除 volatile:" << endl;
	cout << typeid(remove_volatile<decltype(b)>::type).name() << endl;

	cout << "移除引用:" << endl;
	cout << typeid(remove_reference<decltype(c)>::type).name() << endl;
	cout << typeid(remove_reference<decltype(d)>::type).name() << endl;

	// 指针降级
	cout << "移除一级指针:" << endl;
	cout << typeid(remove_pointer<decltype(e)>::type).name() << endl;

	cout << "移除多级指针" << endl;
	cout << typeid(RemomveAllPointers<decltype(f)>::type).name() << endl;
}

// 2. 增加修饰符
void test02()
{
	int a = 100;

	// 1. 增加 const 修饰符
	using NewConstType = add_const<decltype(a)>::type;
	NewConstType aa = 100;
	// 表达式必须是可修改的左值
	// aa = 200;

	// 通过 t 版本直接获得类型
	// add_const_t<decltype(a)> aaa = 100;
	// aaa = 200;

	// 2. 增加指针修饰符
	using NewPointerType = add_pointer<decltype(a)>::type;
	cout << typeid(NewPointerType).name() << endl;

	// 3. 增加左值引用修饰符
	using NewLvalueType = add_lvalue_reference<decltype(a)>::type;
	// 非常量引用的初始值必须为左值
	// NewLvalueType bb = 200; 


	// 4. 增加右值引用修饰符
	using NewRvalueType = add_rvalue_reference<decltype(a)>::type;
	NewRvalueType cc = 100;
}


int main()
{
	test02();
	return 0;
}


#endif

5. 类相关

#if 1
#include <iostream>
#include <type_traits>
using namespace std;

class A {
public:
	A() = delete; 
	A(const A&) = delete;
	A(A&&) = delete;
	virtual ~A() {};
};
class B { virtual void func() {} };
class C { virtual void func() = 0; };



void test()
{
	const int a = 10;

	// 检查类是否是空的(没有非静态数据成员、虚函数或基类)
	cout << "A\t" << is_empty<A>::value << endl;

	// 检查类是否具有多态性(至少一个虚函数)
	cout << "B\t" << is_polymorphic<B>::value << endl;

	// 检查类是否是抽象类(至少一个纯虚函数)
	cout << "C\t" << is_abstract<C>::value << endl;

	// 判断是否可以进行默认构造
	cout << is_default_constructible<A>::value << endl;
	cout << is_copy_constructible<A>::value << endl;
	cout << is_move_constructible<A>::value << endl;
	cout << is_destructible<A>::value << endl;
	cout << has_virtual_destructor<A>::value << endl;
}


int main()
{
	test();
	return 0;
}


#endif

未经允许不得转载:一亩三分地 » C++ Type Traits
评论 (0)

1 + 1 =