如果你这样做:
constexpr int LEN = 100;
LEN
变量定义为const
,无需键入const
关键字
它还具有static
存储空间,无需键入static
关键字。
另一方面,如果我们在class
中执行相同操作:
struct A{
constexpr static int SIZE = 100;
};
SIZE
仍然定义为const
,无需输入const关键字
但SIZE
不是static
数据成员
您需要明确键入static
。如果您没有编译错误。
问题是:
需要明确键入static
的原因是什么?
答案 0 :(得分:1)
static
在两个上下文中都没有相同的含义:
LEN
,static
表示“仅在此编译单元中可用”,因此只有内部链接。这是一个storage specifier
A::SIZE
,static
表示“它是类成员”,因此不会绑定到特定实例 constexpr
可以引用实例或类成员或函数,因此编译器无法在您的位置确定它是否为static
,即绑定或不是特定的例子。它与const
说明符的推理相同。但是,正如你可以想象的那样,拥有一个非静态的constexpr
成员是没有意义的,所以它是被禁止的。示例:
class A
{
int a;
constexpr A(int value): a(value) {}
// constexpr bound to a specific instance
constexpr int getDouble() const
{ return a*2; }
// constexpr not bound to a specific instance
static constexpr int getDouble(int b)
{ return b*2; }
}
全局上下文中的 constexpr
指的是在编译时计算的东西(或者,对于函数,如果不可能在编译时计算,将被内联),因此不需要外部链接等等,与static
全局变量或函数相似的行为(仅可比较,因为使用编译时计算或内联,您也不需要内部链接)
constexpr int a = 5; // Will be replace everywhere by value
/* If b is constexpr, calcul are done at compile time and result will be used
* else double is inlined, so no need of linkage at all
*/
constexpr int getDouble(int b)
{ return b * 2; }
答案 1 :(得分:1)
constexpr
不应该暗示static
,因为constexpr
没有static
是有道理的。考虑:
#include <iostream>
struct Dim
{
constexpr Dim(int a,int b) : a(a), b(b) {}
constexpr int Prod() const { return a*b; }
int a,b;
};
int main()
{
constexpr Dim sz(3,4);
int arr[ sz.Prod() ];
std::cout << sizeof(arr) << std::endl;
}
它也不应该在类定义之外隐含static
由于static
表示“本地翻译单位”和constexpr
不需要。
答案 2 :(得分:0)
我认为你对static
在全球范围内的含义感到困惑,而你的问题是基于这种误解。
LEN
变量定义为const,无需键入const
关键字。
当然constexpr
暗示const
,这不应该令人惊讶。
它还具有
static
存储空间,无需键入static
关键字。
N.B。全局变量始终具有静态存储,因为它的生命周期是全局的。添加static
关键字不会改变它,它的作用是给它内部链接,这意味着它不能通过当前翻译单元之外的名称访问。
constexpr
和const
对全局变量的规则相同:命名空间范围const变量隐含地具有内部链接(这是&#34的多种含义之一;静态&#34;。)
但是类范围const变量没有内部链接,即使你向其添加static
。标记变量static
意味着命名空间范围和类范围完全不同。将static
自动添加到标记为const
或constexpr
的类成员没有意义,因为这意味着与命名空间范围内的变量完全不同。
所以constexpr
暗示const
(显然),在命名空间范围const
意味着内部联系。
在班级范围constexpr
仍然隐含const
,但这对成员变量是否为&#34;类变量&#34;没有任何影响。或者&#34;实例变量&#34;。