2013-01-13 83 views
9

有人能告訴我何時文字類需要C++
我從constexpr構造函數,constexpr成員有點困惑,我看不出有什麼重點。我希望看到它的一些實際用途。我什麼時候應該在C++中使用字面類?

想也想知道,如果一個設置成員函數必須constexpr,即:

constexpr void set_num(int a) { num = a; } 
+0

您不能修改編譯時對象。 –

+0

@VaughnCato我想知道你指的是我的問題的哪一部分。謝謝 – TGO

+2

看來你的'set_num'成員試圖修改一個類的成員。如果'set_num'被聲明爲constexpr,那麼該對象不能被修改,所以你的分配將是無效的。 –

回答

8

在C++ 03此物體具有動態初始化

struct Data { 
    int i; 
    int j; 
}; 
Data init_data(); // calculate something 
const Data data = init_data(); 

即在程序啓動時,前main運行時,該函數將被調用,並且該對象被初始化。

在C++ 11的對象可以具有恆定初始化靜態初始化的一種形式,這意味着它的值被設置在編譯時和在程序開始之前它的初始化。這對於避免static initialization order fiasco等很有用。爲了確保類型獲得的不變初始化它必須由一個常量表達式初始化,因此必須有一個constexpr構造函數,並且在完整表達式中調用的任何函數必須是constexpr函數。

類型Data是微不足道所以它隱含聲明的構造函數是constexpr構造,所以使全球data進行常數初始化我們只需要做出init_data()constexpr功能:

struct Data { 
    int i; 
    int j; 
}; 
constexpr Data init_data(); // calculate something 
constexpr Data data = init_data(); 

優勢文字類型是這樣的類型可以用於其他常量表達式,即在需要編譯時常量的上下文中。所以,現在我們有我們的data對象作爲編譯時常量,我們可以在其他常量表達式中使用它,例如初始化其他的編譯時常:

const int i = ::data.i; 

而且我們可以用在類初始化使用Data類型靜態數據成員:

struct MoreData { 
    static constexpr Data zerozero = Data{}; // OK, Data is a literal type 
}; 

如果Data不是文本類型,我們會寫:

struct MoreData { 
    static const Data zerozero; 
}; 

// in moredata.cc 
const Data MoreData::zerozero = Data{}; 

然後代碼只能看到頭不知道MoreData::zerozero價值和COM不能使用它樁時間優化。

因此,「文字類型」規則的優點是它們允許您定義可以在常量表達式中使用的新類類型。在C++ 03中,常量表達式中只能使用很少的類型,例如整數,例如,整數文字,如10x23或整數類型的編譯時常量。在C++ 11中,你可以編寫自己的類型,它們的構造函數中可以有適度複雜的邏輯(任何可以在constexpr函數中表達的東西),但仍然可以用作編譯時常量。

而且我想知道,如果一組成員函數必須constexpr,即

一個constexpr成員函數是一個const成員函數的一個特例,所以它不能修改(非-mutable)類型的成員。修改對象的setter函數不能是const。

要成爲文字類型,類必須遵循一些規則,包括至少有一個constexpr構造函數。這並不意味着該類型的所有對象必須constexpr常數,它只是意味着該類型的對象可以constexpr常量,如果他們被宣佈爲和使用類constexpr一個構造函數初始化。要再次使用Data例如,在你的程序的大多數對象不會是常數:

Data d = { 0, 1 }; 
d.i = d.i + 5; 

所以,如果你添加一個setter,它修改對象的功能,那就只能是有意義的使用在非const類型的對象,以及修改類型的任何其他函數,它不應該是

4

使用數字界線時C++ 98 constexpr修復問題。 C++ 11如

std::numeric_limits<short>::max() 

不能被用作積分常數,雖然它是幾乎等於宏INT_MAX表達之前。用C++ 11,這樣的表達被聲明爲constexpr使得,例如, 可以用它來聲明陣列編譯時計算(元編程)

std::array<float,std::numeric_limits<short>::max()> a; 
+0

雖然'constexpr'在日常使用中對於這樣的常量返回函數是最有意義的,這當然只有「constexpr」及其用法和含義的真相的一半(並且對於實際問題只有一半的答案)。 –

2

一個大constexpr類的好處是可以將它們放入.ro數據,這可能導致可執行文件的大小減小和性能提升。 ESP。對於幾何類型例如或類似的「簡單」類型,這是非常整潔,因爲你也可以擺脫「魔術」數字。見例如https://www.kdab.com/kdab-contributions-to-qt-5-0-part-4/

相關問題