C++ 模板工厂、支持任意参数代理、模板元编程
C++ 模板工厂、支持任意参数代理、模板元编程
- 一、模板工厂
- 二、支持任意参数代理
- 三、模板元编程
- 1.基本构建块
- 2.编译期 vs 运行时
- 3.例子
- 例子一
- 例子二
- 例子三
一、模板工厂
我们需要创建如下的类型,类型可能有很多个
struct TestObj1
{};struct TestObj2
{
public:TestObj2(){}TestObj2(int a,int b):a(a),b(b){}int a;int b;
};
我们可以用如下模板创建,但是有个弊端,我们无法为创建的对象进行赋值
template<typename T>
T* CreateObject()
{return new T();
}
让我们改进一下
如下图,我们使用可变参数实现了不同遍历的赋值操作,但是每次赋值都会产生拷贝,我们继续优化
template<typename T,typename ...ParamTypes>
T* CreateObject(ParamTypes&&...Param)
{return new T(Param...);
}
使用 #include <type_traits> 下的forward函数,避免拷贝
template<typename T,typename ...ParamTypes>
T* CreateObject(ParamTypes&&...Param)
{return new T(std::forward<ParamTypes>(Param)...);
}
二、支持任意参数代理
代理或者委托就是对函数指针的一种封装
- 需要有调用的实例
- 执行调用的函数指针
- 重载()调用委托
template<typename TObjectType,typename TReturn,typename ...ParamTypes>
class FDelegate
{
public:FDelegate(TObjectType* InObject, TReturn(TObjectType::* InFunction)(ParamTypes...)):Object(InObject), Function(InFunction){}TReturn operator()(ParamTypes&&...Param){return (Object->*Function)(std::forward<ParamTypes>(Param)...);}public:TObjectType* Object;TReturn(TObjectType::* Function)(ParamTypes...);
};template<typename TObjectType, typename TReturn, typename ...ParamTypes>
FDelegate<TObjectType, TReturn, ParamTypes...> CreateDelegate(TObjectType* InObject, TReturn(TObjectType::* InFunction)(ParamTypes...))
{return FDelegate<TObjectType, TReturn, ParamTypes...>(InObject, InFunction);
}
使用如下
DelegateStruct* ds = new DelegateStruct();auto delegate = CreateDelegate(ds, &DelegateStruct::TestFunc);int sum = delegate(1, 2);std::cout << sum << std::endl;
如下是对核心语法 (Object->*Function)(std::forward<>(Param)…) 的解析
为什么要这样设计:
三、模板元编程
模板元编程(Template Metaprogramming,简称TMP)是C++的一项强大技术,利用模板系统在编译期进行计算、生成代码和执行逻辑。它在现代C++开发中扮演着关键角色。
1.基本构建块
- 类型计算:typedef, using别名
- 值计算:static constexpr成员
- 模式匹配:模板特化与偏特化
- 递归实例化:模板递归调用
2.编译期 vs 运行时
3.例子
例子一
定义:
template<class T,T t>
struct FConstTest
{static constexpr T Value = t;
};
使用:
int value1 = FConstTest<int, 10>::Value;std::cout << value1 << std::endl;
例子二
定义:
template<int value1,int value2>
struct FConstTest1
{static constexpr int Value = value1 + value2;
};
使用:
int value2 = FConstTest1<10, 20>::Value;std::cout << value2 << std::endl;
例子三
定义:
template<class T,T t>
struct FConstTest
{static constexpr T Value = t;
};template<bool v>
using bool_temp = FConstTest<bool, v>;template<class , class>
constexpr bool isSame_V = false;template<class T>
constexpr bool isSame_V<T, T> = true;template<class T1,class T2>
struct isSame : bool_temp<isSame_V<T1,T2>>{};
使用:
bool b1 = isSame<int, int>::Value;std::cout << b1 << std::endl;bool b2 = isSame<int, float>::Value;std::cout << b2 << std::endl;