为什么我不能在非常量表达式上使用此模板阶乘函数?

Why can't I use this Template factorial function on a non-constant expression?

本文关键字:阶乘 函数 不能 非常 表达式 常量 为什么      更新时间:2023-10-16

我正在尝试熟悉模板元编程

请考虑以下代码,它使用基本的介绍性阶乘 模板功能在许多在线模板教程中找到。

#include <iostream>
template <int N> struct Factorial {
static const int result = N * Factorial<N-1>::result;
};
template <> struct Factorial<0> {
static const int result = 1;
};
int main() {
int tmp;
std::cin >> tmp;
static const int tmpc = tmp;
std::cout << Factorial<tmpc>::result << "n";
return 0;
}

如果我tmpc=10设置为编译时常量,该示例将完美运行。但是如果 tmpc = tmp 那么,我得到编译错误

templates.cpp: In function ‘int main()’:
templates.cpp:30:29: error: the value of ‘tmpc’ is not usable in a constant expression
std::cout << Factorial<tmpc>::result << "n";
^~~~
templates.cpp:29:23: note: ‘tmpc’ was not initialized with a constant expression
static const int tmpc = tmp;
^~~~
templates.cpp:30:33: error: the value of ‘tmpc’ is not usable in a constant expression
std::cout << Factorial<tmpc>::result << "n";
^
templates.cpp:29:23: note: ‘tmpc’ was not initialized with a constant expression
static const int tmpc = tmp;
^~~~
templates.cpp:30:33: note: in template argument for type ‘int’ 
std::cout << Factorial<tmpc>::result << "n";

这是否意味着,我只能在编译时常量表达式上使用模板化函数?!!!

我的理解哪里出错了?

这是否意味着,我只能在编译时使用模板化函数 常量表达式?!!!

注意术语。模板函数可以使用运行时值,但元函数不能,因为它(根据定义(在编译时计算。

函数模板更普通一些:

template <typename T>
void f(T arg) { /*...*/ }

调用 f(( 将导致对所使用的每个唯一类型进行不同的 f(( 实例化,但它仍然是采用运行时值的运行时函数。

对于元函数,参数本身是模板参数,模板参数不能是运行时值。

我只能在编译时常量表达式上使用模板化函数?

是的。模板在编译时进行评估。