C++ 模板参数展开

C++ 模板参数展开


一、获取可变参数大小

背景:

FLen<int, char, long> Len;

我想要获取模板参数类型的总大小

cpp 复制代码
template<typename T,typename ...ParamTypes>
class FLen
{
public:
	enum
	{
		Number = FLen<T>::Number + FLen<ParamTypes...>::Number
	};
};

template<typename Last>
class FLen<Last>
{
public:
	enum
	{
		Number = sizeof(Last)
	};
};

思想还是类似递归调用的思想,只是递归的不是函数而是模板

cpp 复制代码
int main()
{
	FLen<int, char, long> Len;

	std::cout << Len.Number << std::endl;

	system("pause");
	return 0;
}

二、通过模版循环继承的方式来展开可变参数

最终目的是构建一个 TestIndex 类型,其模板参数是从0开始到N-1的整数序列。

cpp 复制代码
template<int...>
struct TestIndex
{

};

template<int N,int...ParamTypes>
struct FSpawnIndex : FSpawnIndex<N - 1,N - 1,ParamTypes...>
{

};

template<int...ParamTypes>
struct FSpawnIndex<0,ParamTypes...>
{
	typedef TestIndex<ParamTypes...> Type;
};

解释一下原理和流程

起始:FSpawnIndex<3>(此时 N=3,参数包为空)

继承:FSpawnIndex<3> : FSpawnIndex<2,2>

在内部,参数包变为 2

下一步:FSpawnIndex<2,2> : FSpawnIndex<1,1,2>

参数包变为 1,2(注意:每次递归在参数包头部添加)

下一步:FSpawnIndex<1,1,2> : FSpawnIndex<0,0,1,2>

参数包变为 0,1,2

匹配终止条件:FSpawnIndex<0,0,1,2>

定义 Type 为 TestIndex<0,1,2>

cpp 复制代码
int main()
{
	using TestType = FSpawnIndex<3>::Type;

	std::cout << typeid(TestType).name() << std::endl;

	system("pause");
	return 0;
}

三、改用Using去实现循环继承

cpp 复制代码
template<int...>
struct TestIndex
{

};

template<int N,int...ParamTypes>
struct FSpawnIndex
{
	using Type = typename FSpawnIndex<N - 1, N - 1, ParamTypes...>::Type;
	//          ↑↑↑↑↑
	// 这个 typename 必不可少!
};

template<int...ParamTypes>
struct FSpawnIndex<0, ParamTypes...>
{
	typedef TestIndex<ParamTypes...> Type;
};

在 C++ 模板元编程中,typename 关键字在这里起着​​关键作用​​,主要用于解决​​依赖名称的解析问题​​。

cpp 复制代码
int main()
{
	using TestType = FSpawnIndex<3>::Type;

	std::cout << typeid(TestType).name() << std::endl;

	system("pause");
	return 0;
}

​​什么是依赖名称?​​

FSpawnIndex<N-1, ...>::Type 是​​依赖于模板参数 N 和 ParamTypes... 的名称​​

编译器在解析模板时,无法确定 ::Type 是什么(可能是类型、静态成员或嵌套模板)

例如以下例子

cpp 复制代码
// 情况分析:
struct FSpawnIndex</*...*/> {
    // 可能1:Type 是类型(typedef/using)
    typedef ... Type;

    // 可能2:Type 是静态成员
    static int Type;

    // 可能3:Type 是嵌套模板
    template<...> class Type;
};
相关推荐
꧁Q༒ོγ꧂11 分钟前
算法详解(三)--递归与分治
开发语言·c++·算法·排序算法
李兴球27 分钟前
这个来自五线城市的C++兴趣班的程序可不一般
c++
White_Can1 小时前
《C++11:智能指针》
c++·c++11·智能指针
无限进步_1 小时前
【数据结构&C语言】对称二叉树的递归之美:镜像世界的探索
c语言·开发语言·数据结构·c++·算法·github·visual studio
im_AMBER1 小时前
Leetcode 98 从链表中移除在数组中存在的节点
c++·笔记·学习·算法·leetcode·链表
CSDN_RTKLIB1 小时前
C++取模与取余
开发语言·c++
星河耀银海1 小时前
C++开发入门——环境搭建与第一个程序
开发语言·c++·策略模式
_OP_CHEN2 小时前
【算法基础篇】(四十四)数论之欧拉定理与扩展欧拉定理深度解析:从降幂到超大规模幂运算
c++·算法·蓝桥杯·算法竞赛·欧拉定理·扩展欧拉定理·acm/icpc
liulilittle3 小时前
DeepWiki: OPENPPP2 工程价值
网络·c++·网络协议·ai·信息与通信·通信
星河耀银海3 小时前
C++面向对象编程:从基础到实战
开发语言·c++