为何非类型模板参数不能依赖模板特化的参数?
关于C++模板特化中[temp.class.spec] 14.5.5/8条款的疑问
问题重现
我编写了如下C++代码:
#include <iostream> template <typename num_t, num_t num> struct factorial { consteval operator num_t() { return num * factorial<num_t, num - 1>{}; } }; template <typename num_t> struct factorial<num_t, 2> { consteval operator char() { return 2; } }; int main() { std::cout << factorial<unsigned long long, 20>{} << '\n'; }
Clang在struct factorial<num_t, 2>的2处报错,错误信息为:
error: non-type template argument specializes a template parameter with dependent type 'num_t'
对应的C++标准条款
查询后发现这符合C++标准[temp.class.spec] 14.5.5/8条款的规定,原文如下:
Paragraph [temp.class.spec] 14.5.5/8 of the standard:
The type of a template parameter corresponding to a specialized non-type argument shall not be dependent on a parameter of the specialization. [ Example:
template <class T, T t> struct C {};
templatestruct C<T, 1>;; // error template< int X, int (*array_ptr)[X] > class A {};
int array[5];
template< int X > class A<X,&array> { }; // error
—end example ]
条款通俗翻译
人话版解释:在类模板的特化中,用来匹配原模板非类型参数的实参,它的类型不能依赖于当前特化模板的参数。简单说就是,特化时给的非类型实参,其类型必须是确定的,不能跟着特化模板的参数动态变化。
核心疑问
我想了解:
- 该标准条款制定的具体原因是什么?
- 这条规则具备哪些实际或理论层面的价值?
内容的提问来源于stack exchange,提问作者Nik Tedig
相关产品推荐
相关产品推荐

