以下是C ++ Primer第5版(重点是我的)的摘录:
非类型参数可以是整数类型,也可以是指针或(左值) 引用对象或函数类型。一个与a绑定的参数 nontype积分参数必须是常量表达式。 参数 绑定到指针或引用nontype参数必须具有静态 一生(第12章,第450页)。我们可能不会使用普通(非静态) 本地对象或动态对象作为参考模板参数 或指针非类型模板参数。指针参数也可以 由nullptr或零值常量表达式实例化。
在此段落的正下方,可以找到突出显示的注释:
用于非类型模板参数的模板参数必须是 常数表达式。
也许我错过了什么,但我认为Note是错误的,因为指针的非类型模板参数或对象或函数类型的左值引用不是常量表达式。
答案 0 :(得分:2)
如果您担心下面的非类型指针,则您对具有非函数模板参数的非指针的结构具有完全有效的特化:
void foo() { }
template <void(*)()>
struct bar { };
int main() {
bar<&foo> b;
}
此处&foo
也是一个常量表达式,因为它具有静态生命周期。
正如Revolver_Ocelot提到的5.20 [expr.const] / 5和5.2明确指出:
常量表达式是glvalue核心常量表达式 其值是指一个允许的结果的实体 常量表达式(如下定义)或prvalue核心常量 表达式,其值是一个对象,对于该对象及其对象 子对象:
(...)
- 如果对象或子对象是指针类型,则它包含具有静态存储持续时间的对象的地址,过去的地址 这样一个对象的结尾(5.7),一个函数的地址,或者一个null 指针值
(我使用了草案N4296)