以下程序编译: 通用标签

但是,这不是,这让我感到惊讶: 通用标签

替代示例: 通用标签

我已经得出结论,无论指针是否为const并使用常量表达式初始化,指针都不能是常量表达式。

问题:

  1. 我的结论正确吗?
  2. 如果是这样,为什么指针不能是常量表达式?如果没有,为什么上面的程序不能编译?
  3. C ++ 0x(如果需要,可以使用C ++ 11)更改任何内容吗?

    感谢您的见解!

有帮助吗?

解决方案

有点复杂。在C ++ 03和C ++ 11中,如果&var是局部static / class static或命名空间范围变量,则var是常量表达式。这称为地址常量表达式。可以保证在运行任何代码之前(静态初始化阶段)使用该常量表达式初始化类静态或名称空间作用域指针变量,因为它是一个常量表达式。

但是,仅从C ++ 11开始,用于存储地址&var constexpr 指针变量也可以用作地址常量表达式,并且仅从C ++ 11开始,您才可以取消引用地址常量表达式(实际上,您甚至可以取消引用-甚至包括本地数组元素地址,但让我们保留其为主题),如果它引用的是在取消引用之前初始化的常量整数变量或constexpr变量,则您将再次获得一个常量表达式(类型和值类别,常量表达式的种类可能会有所不同)。因此,以下是有效的C ++ 11: 通用标签

如果是这样,为什么指针不能是常量表达式?如果没有,为什么上面的程序不能编译?

这是标准措辞中的一个已知限制-当前,它仅允许将其他模板参数用作指针类型的模板参数的自变量或& object。即使编译器应该能够做更多的事情。

其他提示

在C ++ 0x中仍然不允许。 temp.arg.nontype要求:

非类型,非模板模板参数的模板参数应为以下之一:

  • 对于整数或枚举类型的非类型模板参数,使用该模板参数类型的转换后的常数表达式(5.19);或
  • 非类型模板参数的名称;或
  • 一个常数表达式(5.19),用于指定具有静态存储持续时间和 外部或内部链接或具有外部或内部链接的功能,包括功能模板 和功能模板ID,但不包括非静态类成员,表示为(忽略括号)为 & id-expression ,但如果&指代函数或数组,并且&可以省略,则&可以省略 如果相应的模板参数是参考,则将其省略;或
  • 一个常量表达式,其结果为空指针值(4.10);或
  • 一个常量表达式,其值为空成员指针值(4.11);或
  • 指向成员的指针,如5.3.1所述。

    原始答案:

    1. 在C ++ 03中,只有整数表达式可以是常量表达式。
    2. 因为标准是这样(自然)这样的。
    3. 在C ++ 0x中,n3290包括在指针上使用constexpr的示例。因此,尽管现在必须使用constexpr关键字而不是顶层const关键字,但您现在应该可以尝试执行该操作。

      还存在一个gcc错误, g ++拒绝了标准草案自己的有效constexpr用法示例。

问题是因为您的C ++程序可以在内存中的任何位置加载,因此,每次运行该程序时,全局var的地址可能会有所不同。如果两次运行程序会怎样?然后,var显然位于两个不同的位置。

更糟糕的是,在您的示例中,您采用了堆栈上变量的地址!看这个: 通用标签

如果main调用myfunction(3),则会在单独的位置创建3个myvar。编译时间甚至无法知道如何创建许多 myvars,更不用说确切的位置了。

最后:声明一个变量为const意味着:“我保证”,而不是意味着这是一个编译时间常数。参见以下示例: 通用标签

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top