C++ 模板元编程 type_traits
C++ 模板元编程 type_traits
- 一、type_traits 中的常用判断方式
- 二、is_same比较的一些案例
- 1.add_lvalue_reference,add_rvalue_reference
- 2.remove_const,add_const
- 三、conditional
- 四、decay
- 五、enable_if
- 1.简单使用:
- 2.举一反三:
一、type_traits 中的常用判断方式
为了之后我们的例子,先创建一些测试的类型
class TestClass
{};class FTestStruct
{};enum MyEnum : char
{ETest1,ETest2,
};class FInterface
{virtual void Init() = 0;};class ChilClass : public FInterface
{virtual void Init() override{}
};
开始对常用的方法进行逐一测试
int main()
{std::cout << "========is_same=======" << std::endl;std::cout << std::is_same<int, int>::value << std::endl;std::cout << std::is_same<int, float>::value << std::endl;std::cout << "========is_class=======" << std::endl;std::cout << std::is_class<TestClass>::value << std::endl;std::cout << std::is_class<FTestStruct>::value << std::endl;std::cout << "========is_enum=======" << std::endl;std::cout << std::is_enum<MyEnum>::value << std::endl;std::cout << "========is_integral=======" << std::endl;std::cout << std::is_integral<int>::value << std::endl;std::cout << std::is_integral<char>::value << std::endl;std::cout << std::is_integral<float>::value << std::endl;std::cout << "========is_floating_point=======" << std::endl;std::cout << std::is_floating_point<float>::value << std::endl;std::cout << std::is_floating_point<int>::value << std::endl;std::cout << std::is_floating_point<double>::value << std::endl;std::cout << "========is_pointer=======" << std::endl;std::cout << std::is_pointer<float*>::value << std::endl;std::cout << std::is_pointer<int*>::value << std::endl;std::cout << "========is_lvalue_reference=======" << std::endl;std::cout << std::is_lvalue_reference<int&>::value << std::endl;std::cout << std::is_lvalue_reference<float&>::value << std::endl;std::cout << "========is_rvalue_reference=======" << std::endl;std::cout << std::is_rvalue_reference<int&&>::value << std::endl;std::cout << std::is_rvalue_reference<float&&>::value << std::endl;std::cout << "========is_function=======" << std::endl;std::cout << std::is_function<int>::value << std::endl;std::cout << std::is_function<void()>::value << std::endl;std::cout << std::is_function<void(int,int)>::value << std::endl;std::cout << std::is_function<int(int,int)>::value << std::endl;std::cout << std::is_function<int(...)>::value << std::endl;std::cout << "========is_member_function_pointer=======" << std::endl;std::cout << std::is_member_function_pointer<int(TestClass::*)(int,int)>::value << std::endl;std::cout << "========is_member_object_pointer=======" << std::endl;std::cout << std::is_member_object_pointer<float(TestClass::*)>::value << std::endl;std::cout << "========is_array=======" << std::endl;std::cout << std::is_array<std::vector<int>>::value << std::endl;std::cout << std::is_array<int[]>::value << std::endl;std::cout << "========is_arithmetic=======" << std::endl;std::cout << std::is_arithmetic<int>::value << std::endl;std::cout << std::is_arithmetic<float>::value << std::endl;std::cout << "========is_abstract=======" << std::endl;std::cout << std::is_abstract<FInterface>::value << std::endl;std::cout << std::is_abstract<ChilClass>::value << std::endl;system("pause");return 0;
}
测试结果:
二、is_same比较的一些案例
根据前面的知识我们可以知道,这样是不相同的
那么如何转换成相同类型呢
std::cout << std::is_same<int&, int>::value << std::endl;
1.add_lvalue_reference,add_rvalue_reference
std::cout << std::is_same<int&, std::add_lvalue_reference<int>::type>::value << std::endl;std::cout << std::is_same<int&&, std::add_rvalue_reference<int>::type>::value << std::endl;
2.remove_const,add_const
std::cout << std::is_same<int, std::remove_const<const int>::type>::value << std::endl;std::cout << std::is_same<const int, std::add_const<int>::type>::value << std::endl;
三、conditional
有点类似三目运算符
std::conditional<true, int, float>::type type1 = 10;std::conditional<false, int, float>::type type2 = 10;std::cout << typeid(type1).name() << std::endl;std::cout << typeid(type2).name() << std::endl;
可以看到运行后的结果
也可以加bool判断的表达式
如下:
std::conditional<(2 < 3), int, float>::type type;
那么是如何实现的呢?
答案就是模板的匹配,true匹配一个模板,false匹配另外一个模板
可以看到下图的源码,定义了一个泛型模板,一个特化模板,由于优先匹配特化模板若没有匹配再去找泛化模板的顺序,故实现了此功能!
四、decay
decay 是用于去除修饰符的
可以看到如下代码,去除前后的变化
std::decay<int&>::type A1;//intstd::decay<int&&>::type A2;//intstd::decay<const int>::type A3;//intstd::decay<int[100]>::type A4;//int*std::decay<int(int)>::type A5;//int(*)(int)
五、enable_if
比如我们只想根据传入函数参数的类型来进行限定可以使用enable_if
1.简单使用:
struct MyStruct
{};template<class T>
typename std::enable_if<std::is_arithmetic<T>::value, T>::type Func(T t)
{std::cout << "Run1" << std::endl;return t;
}template<class T>
typename std::enable_if<!std::is_arithmetic<T>::value, T>::type Func(T t)
{std::cout << "Run2" << std::endl;return t;
}
使用:
这样可以限定传入参数的类型,根据不同类型的参数做不同的操作
MyStruct myStruct;int value1 = Func(1);float value2 = Func(1.2f);Func(myStruct);
2.举一反三:
template<class T>
void Func1(typename std::enable_if<std::is_arithmetic<T>::value, T>::type t)
{std::cout << "Run3" << std::endl;
}template<class T>
void Func1(typename std::enable_if<!std::is_arithmetic<T>::value, T>::type t)
{std::cout << "Run4" << std::endl;
}
Func1<int>(2);Func1<float>(2.3f);Func1<MyStruct>(myStruct);