关于第一个问题,我不是编译器专家,但我可以猜测它使编译器的生活更轻松,也许这是来自旧版本的 C++ 的限制,其中constexpr
不可用。
尽管如此,C++11 标准的第 14.3.2/1 段非常清楚什么是允许的,什么是不允许的:
非类型、非模板模板参数的模板参数应为以下之一:
——对于整数或枚举类型的非类型模板参数,模板参数类型的转换常量表达式(5.19);或者
— 非类型模板参数的名称;或者
—一个常量表达式 (5.19),它指定具有静态存储持续时间和外部或内部链接的对象或具有外部或内部链接的函数的地址,包括函数模板和函数模板 ID,但不包括非静态类成员,表示为 (忽略括号)作为 & id-expression,但如果名称引用函数或数组,则 & 可以省略,如果相应的模板参数是引用,则应省略;或者
— 一个常量表达式,计算结果为空指针值 (4.10);或者
— 一个常量表达式,其值为空成员指针值 (4.11);或者
— 一个指向成员的指针,如 5.3.1 所述;或者
— std::nullptr_t 类型的地址常量表达式。
相反,关于第二个问题, achar
是允许的。例如,以下是一个合法程序:
template<char c>
struct X
{
// ...
};
int main()
{
X<'c'> x;
}
关于不允许使用浮点类型的原因,您可以在 StackOverflow 上的 Q&A中找到一些信息。