这似乎是C Primer第5版中的错误

This seems to be an error in the book C++ Primer 5th edition

本文关键字:错误 5版 似乎是 Primer      更新时间:2023-10-16

以下是《 C 底漆》第5版(重点是我的)的摘录:

非类型参数可以是积分类型,或者是指指针或(lvalue) 引用对象或功能类型。一个绑定到一个的论点 非型积分参数必须是恒定表达式。参数 绑定到指针或参考非类型参数必须具有静态 Lifetime (第12章,第450页)。我们可能不会使用普通(非静态) 本地对象或动态对象作为模板参数用于参考 或指针非类型模板参数。指针参数也可以 通过NULLPTR或零值的常数表达来实例化。

就在本段下方,可以找到此突出显示的注释:

用于非类型模板参数的模板参数必须为 恒定表达式。

也许我缺少某些内容,但我相信注释是错误的,因为指针或lVALUE对对象或函数类型的非类型模板参数不是恒定的表达式。

如果您担心下面的非类型指针,则具有具有非类型指针的结构的完全有效的专业化来函数模板参数:

void foo() { }
template <void(*)()>
struct bar { };
int main() {
   bar<&foo> b; 
}

&foo这里也是一个恒定的表达式,因为它具有静态寿命。

正如Revolver_ocelot提到的5.20 [expr.const]/5和5.2清楚地指出:

常数表达是glvalue核心常数表达式 其价值是指一个实体,该实体是a的允许结果 恒定表达(如下定义)或prvalue核心常数 表达式的价值是一个对象,对于该对象及其对象 子对象:

(...)

  • 如果对象或子对象是指针类型,则包含具有静态存储持续时间的对象的地址,地址过去 这样的对象的末端(5.7),函数的地址或null的末端 指针值

(我使用了N4296草案)