是否允许存在永远无法实例化的C++模板?相关规则咨询
C++模板实例化规则相关问题解答
一、可变参数模板的规则是否适用于普通模板?
你提到的可变参数函数模板必须能以非空包实例化的规则,并不适用于普通类模板或非可变参数函数模板。普通模板没有强制要求必须存在合法的实例化路径,只要模板定义本身符合语法和依赖规则,哪怕所有可能的实例化都会报错,定义依然是格式良好的。
分析给出的代码示例:
template <int N> struct array { // 实例化时总是非法,但表达式依赖于N,编译器允许通过 int arr[N * 0]; }; template <int N> void foo() { int arr[N * 0]; // 同上 }
这段代码是格式良好的,原因如下:
- 在模板定义阶段,编译器仅检查语法正确性与依赖表达式的合法性(比如
N*0是依赖模板参数的合法表达式),不会提前验证所有模板参数代入后的结果。 - 只有当模板被实际实例化(比如声明
array<10> a;或调用foo<5>();)时,编译器才会检查实例化后的代码:此时int arr[0]属于零长度数组,不符合C++标准要求,会触发编译错误,但模板定义本身合法,不属于“格式错误无需诊断”的范畴。
二、添加全偏特化后,主模板无法实例化的情况
如果给array添加如下约束为true的全偏特化:
template <int N> requires true struct array<N> {};
此时所有对array<N>的实例化都会优先匹配这个特化,主模板永远不会被实例化,但主模板的定义依然是格式良好的。
C++标准并不要求模板必须存在可被实例化的场景,只要模板定义本身符合语法和依赖规则,哪怕它永远不会被用到,也不会影响代码的合法性。
内容的提问来源于stack exchange,提问作者Jan Schultke
相关产品推荐
相关产品推荐

