在回答这个 SO question& id-expression
时,我在标准(已经是 C++03,仍在 C++11 中)中发现,如果地址的格式为(加上一些例外),则只能将地址用作非类型模板参数。
但我无法回答为什么会这样。
14.3.2 模板非类型参数 [temp.arg.nontype]
非类型、非模板模板参数的模板参数应为以下之一:
[...]
— 一个常量表达式 (5.19),它指定具有静态存储 > 持续时间和外部或内部链接的对象或具有外部或内部链接的函数的地址,包括函数模板和函数模板 ID,但不包括非静态类成员,表示(忽略括号)为 & id-expression,但如果名称引用函数或数组,则 & 可以省略,如果相应的模板参数是引用,则应省略;[...]
(n3485,强调我的)
例子:
using TFoobar = int (*)();
template < TFoobar tp > struct foo_struct{};
int foobar() { return 42; }
constexpr TFoobar pFoobar = &foobar;
foo_struct < &foobar > o0; // fine
foo_struct < pFoobar > o1; // ill-formed
我想这与翻译阶段有关,即编译器对地址了解不多。然而,为什么不允许呢?编译器不应该使用类似于宏替换的东西来替换pFoobar
吗&foobar
?