为什么模板非类型形参指针和引用实参需要是全局的

Why template nontype parameter pointer and reference arguments needs to be global

本文关键字:实参 全局 引用 类型 指针 形参 为什么      更新时间:2023-10-16

为什么作为非类型参数传递的参数应该是全局的而不是局部的?不是在编译期间创建和分配内存吗?

在这种情况下,p是一个const指针,所以它不能指向任何其他变量,也不能给出错误,为什么?

template<int* ptr>
class A{};
int x;
int *const p = &x;
int main() {
    x = 9;
    A<&x> ob;
    A<p> ob2;//giving error
    cin.get();
}

为什么只允许整型作为非类型参数,而不允许char或float?

关于第一个问题,我不是编译器专家,但我可以猜测它使编译器的生活更容易,也许这是来自旧版本的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类型的地址常量表达式。

关于你的第二个问题,相反,char 是允许的。例如,下面是一个合法的程序:

template<char c>
struct X
{
    // ...
};
int main()
{
    X<'c'> x;
}

关于不允许浮点类型的原因,您可以在StackOverflow的问答中找到一些信息。