我有一个关于使用const变量作为模板参数的问题。
使用 gcc 和 clang x64 trunk可以很好地编译以下内容:
template <int N>
void func() { }
int main(int argc, char *argv[]) {
const int x = 12;
func<x>();
}
Run Code Online (Sandbox Code Playgroud)
然而,正如人们所预料的那样,这个版本main()无法编译:
int main(int argc, char *argv[]) {
const int x = argc;
func<x>();
}
Run Code Online (Sandbox Code Playgroud)
不应该x被要求吗constexpr?或者,当该值可以在编译时确定时,是const隐式的吗?constexpr
通常,如果您想在常量表达式中使用变量的值(即在编译时求值中),则必须对变量进行标记,constexpr正如模板参数所要求的那样。
但是,整型和枚举类型有一个例外const,假设它们本身是用常量表达式初始化的,也允许以这种方式使用它们。
在第一个示例中,x使用常量表达式初始化。在你的第二个例子中,它显然不是(因为argc是函数参数)。
这种例外是有历史原因的。在发明之前就已经可以以const这种方式使用积分/枚举变量constexpr(首次出现在 C++11 中)。如果没有这样的规则,在 C++11 之前就没有任何方法可以提供命名的非类型模板参数或数组边界,除非通过预处理器宏(如没有 VLA 的 C 的情况)。而且,由于新的 C++ 版本不应该对旧代码造成不必要的破坏,因此该异常仍然存在。