Constexpr 建構子 (C++11)
附註: IBM 在批准之前支援 C++11的選定特性,稱為 C++0x 。 IBM 將繼續開發並實作此標準的特性。 語言層次的實作是以 IBM的標準解譯為基礎。 在 IBM的所有 C++11 特性實作完成 (包括支援新的 C++11 標準程式庫) 之前,實作可能會在不同版本之間變更。 IBM 不會嘗試維護程式碼、二進位或清單及其他編譯器介面中的相容性,以及舊版 IBM的新 C++11 特性實作。
以宣告的建構子constexpr指定元constexpr建構子。 先前,只有內建類型的表示式可以是有效的常數表示式。 與constexpr建構子,使用者定義類型的物件可以併入有效的常數表示式中。
的定義constexpr建構子必須滿足下列需求:
- 包含類別不得有任何虛擬基礎類別。
- 每一個參數類型都是文字類型。
- 它的功能體是 = delete或=
default; 否則,它必須滿足下列限制:
- 它不是函數嘗試區塊。
- 其中的複合陳述式必須只包含下列陳述式:
- null陳述式
- static_assert宣告
- typedef未定義類別或列舉的宣告
- using指引
- using宣告
- 起始設定每一個非靜態資料成員及基礎類別子物件。
- 用於起始設定非靜態資料成員及基礎類別子物件的每一個建構子都是constexpr建構子。
- 成員起始設定元 ID 未命名之所有非靜態資料成員的起始設定元是常數表示式。
- 起始設定資料成員時,下列環境定義中涉及的所有隱含轉換都必須在常數表示式中有效:
- 呼叫任何建構子
- 將任何表示式轉換為資料成員類型
隱含定義的預設建構子會執行類別的起始設定集,該類別將由使用者撰寫且沒有起始設定元及空複合陳述式的預設建構子執行。 如果該使用者定義的預設建構子將滿足constexpr建構子,隱含定義的預設建構子是constexpr建構子。
Aconstexpr建構子隱含在行內。
下列範例示範的用法constexpr建構子:
struct BASE {
};
struct B2 {
int i;
};
//NL is a non-literal type.
struct NL {
virtual ~NL() {
}
};
int i = 11;
struct D1 : public BASE {
//OK, the implicit default constructor of BASE is a constexpr constructor.
constexpr D1() : BASE(), mem(55) { }
//OK, the implicit copy constructor of BASE is a constexpr constructor.
constexpr D1(const D1& d) : BASE(d), mem(55) { }
//OK, all reference types are literal types.
constexpr D1(NL &n) : BASE(), mem(55) { }
//The conversion operator is not constexpr.
operator int() const { return 55; }
private:
int mem;
};
struct D2 : virtual BASE {
//error, D2 must not have virtual base class.
constexpr D2() : BASE(), mem(55) { }
private:
int mem;
};
struct D3 : B2 {
//error, D3 must not be a function try block.
constexpr D3(int) try : B2(), mem(55) { } catch(int) { }
//error, illegal statement is in body.
constexpr D3(char) : B2(), mem(55) { mem = 55; }
//error, initializer for mem is not a constant expression.
constexpr D3(double) : B2(), mem(i) { }
//error, implicit conversion is not constexpr.
constexpr D3(const D1 &d) : B2(), mem(d) { }
//error, parameter NL is a non-literal type.
constexpr D3(NL) : B2(), mem(55) { }
private:
int mem;
};