簡體   English   中英

為什么在類中初始化的非整數靜態數據成員必須是constexpr?

[英]Why must non-integral static data members initialized in the class be constexpr?

在類定義中初始化的靜態整數數據成員可以聲明為constconstexpr ,但在類定義中初始化的非整數靜態數據成員必須是constexpr

class MyClass {
  static const     int   w = 5;          // okay
  static constexpr int   x = 5;          // okay
  static const     float y = 1.5;        // error!
  static constexpr float z = 1.5;        // okay
};

有人知道為什么不允許y的聲明嗎? 標准中將其定為非法的部分是9.4.2 / 3,但為什么它是非法的?

在C ++ 11之前,您無法在類聲明中初始化非整數/枚舉類型的靜態成員(但您可以在類聲明之外)。 管理constexpr的規則帶有前向,但允許您在類聲明中使用constexpr初始化它(因此您不再需要如下代碼):

struct A
{
    static const float pi;
};

const float A::pi = 3.1415;

這條規則的一個副作用是簡化你的類結構,而不是讓它變得丑陋(如上面的代碼)。

在C ++ 11添加constexpr之前就是這種情況的原因之一是標准沒有指定如何實現浮點(它留給處理器/體系結構 - 例如,當你說float x = 1.6f ,在大多數系統上實際上是1.6000000000024 )。

float是一個更難描述的動機,但想象一個類成員:

class MySpecialInt {
public:
    constexpr MySpecialInt(const int & other) {
    }
};
class MyClass {
    static const     MySpecialInt a = 5; // error
    static constexpr MySpecialInt b = 5; // okay
};

a在這種情況下可能有一些潛在違反(或至少嚴重復雜化)的一個定義規則不平凡的建設。 因為constexpr保證了限制性編譯時屬性,所以b的拷貝構造函數也必須constexpr ,因此保證在編譯時返回一個定義良好的值(並且違反one-definition-rule)

為什么float表現出這種行為,我認為這只是出於遺留原因,因為float從來沒有傳統上像這樣初始化(“因為標准說的是這樣”),所以他們抓住了在constexpr的保護下初始化static const float成員。

這可能是因為非整數i也可能包含像char這樣的數據類型,這就是為什么你不能使它們保持不變並需要常量表達的原因。但是在積分的情況下,你可以使它們成為常量表達式或常量。 因此,由於char只能是一個常量表達式,因此對於所有非整數值都是非法的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM