C++模板实现数组秩计算:模板匹配与推导原理问询
数组秩计算模板的匹配逻辑解析
我找到并调试了一段计算数组秩(rank,即数组维度)的代码——示例中float[4]数组的秩为1,float[3][2]数组的秩为2。
以下是使用cppinsights生成的代码:
#include <iostream> template<typename T> struct Rank { inline static constexpr const size_t value = 0; }; /* First instantiated from: insights.cpp:13 */ #ifdef INSIGHTS_USE_TEMPLATE template<> struct Rank<float[2][1]> { inline static constexpr const size_t value = 1U + Rank<float[1]>::value; }; #endif /* First instantiated from: insights.cpp:13 */ #ifdef INSIGHTS_USE_TEMPLATE template<> struct Rank<float[1]> { inline static constexpr const size_t value = 1U + Rank<float>::value; }; #endif /* First instantiated from: insights.cpp:13 */ #ifdef INSIGHTS_USE_TEMPLATE template<> struct Rank<float> { inline static constexpr const size_t value = 0; }; #endif /* First instantiated from: insights.cpp:18 */ #ifdef INSIGHTS_USE_TEMPLATE template<> struct Rank<float[3][2][1]> { inline static constexpr const size_t value = 1U + Rank<float[2][1]>::value; }; #endif template<typename T, size_t N> struct Rank<T[N]> { inline static constexpr const size_t value = 1U + Rank<T>::value; }; int main() { /* PASSED: static_assert(Rank<float[3][2][1]>::value == 3); */ return 0; }
代码可正常运行,但我无法理解编译器如何将Rank<float[3][2][1]>转换为Rank<float[2][1]>并推导出N=3,如下方实例化代码所示:
template<> struct Rank<float[3][2][1]> { inline static constexpr const size_t value = 1U + Rank<float[2][1]>::value; };
原模板声明为:
template <typename T, size_t N> struct Rank<T[N]> { static constexpr size_t value = 1U + Rank<T>::value; };
这是一个模板偏特化,Rank<float[3][2][1]>的实例会被映射为:
struct Rank<float[3][2][1]> { inline static constexpr const size_t value = 1U + Rank<float[2][1]>::value; };
核心逻辑解析
这不是字符串正则匹配,而是C++模板基于数组类型本质的推导规则:
- C++中多维数组是数组的数组,比如
float[3][2][1]的本质是「包含3个元素的数组,每个元素是float[2][1]类型的数组」。 - 偏特化模板
Rank<T[N]>专门匹配任意一维数组类型:
当编译器处理Rank<float[3][2][1]>时,会将其与Rank<T[N]>的模式匹配:- 最外层数组的长度就是模板参数
N,即3; - 数组的元素类型就是模板参数
T,即float[2][1](因为float[3][2][1]等价于T[N],其中T=float[2][1],N=3)。
- 最外层数组的长度就是模板参数
- 因此偏特化中的
value计算式1U + Rank<T>::value就变成了1U + Rank<float[2][1]>::value,以此递归:Rank<float[2][1]>匹配偏特化,得到N=2,T=float[1],value=1+Rank<float[1]>::valueRank<float[1]>匹配偏特化,得到N=1,T=float,value=1+Rank::value Rank<float>匹配基础模板,value=0- 最终递归计算结果:1+1+1+0=3,符合预期。
内容的提问来源于stack exchange,提问作者Programmer
相关产品推荐
相关产品推荐

