[英]Are functions calls in a constructor's initializer-list sequenced?
考慮:
int f () {
static int i = 0;
return i++;
}
struct Test {
int a, b;
Test () : a(f()), b(f()) {}
};
Test t;
我知道, a
是前初始化b
由於他們在聲明的順序struct
。
我也知道g(f(), f())
中對f
的兩個調用是未排序的。
所以我想知道是否可以保證ta == 0
和tb == 1
?
所以我想知道是否可以保證
ta == 0
和tb == 1
?
這將始終是真實的,只要a
談到之前b
在類聲明中,並沒有別的調用f()
的初始化之間的a
和b
。 類成員按照在類中聲明的順序進行初始化。 [class.base.init] / 11:
在非委托的構造函數中,初始化按以下順序進行:[...]
- 然后,非靜態數據成員按照它們在類定義中聲明的順序進行初始化(同樣,無論mem-initializer的順序如何)。
因此,由於a
在b
之前,所以當構造函數初始化a
,它將第一次調用f()
,然后在初始化b
時將第二次調用它。
我們也知道成員初始化器之間有一個序列點,因為[class.base.init] / 7:
各個mem初始化器執行的初始化構成一個完整表達式。 mem初始化程序中的任何表達式都將作為執行初始化的全表達式的一部分進行評估。
告訴我們每個初始化程序都是一個完整表達式,每個完整表達式都經過排序:[intro.execution] / 14
在與要評估的下一個完整表達式關聯的每個值計算和副作用之前,對與一個完整表達式關聯的每個值計算和副作用進行排序。
我知道a由於在結構中聲明的順序而在b之前初始化。
確實如此。
我該約束的解釋是, a
不能被初始化之前b
除非初始化表達式的評估完成之前, b
被初始化。
我在標准中看不到任何有關對用於初始化非靜態成員的表達式的求值進行排序的內容。 但是,我在C ++ 11標准(12.6.2 / 12)中看到以下示例:
mem初始化程序的expression-list或braced-init-list中的名稱在為其指定了mem-initializer的構造函數的范圍內進行評估。 [ 示例:
class X { int a; int b; int i; int j; public: const int& r; X(int i): r(a), b(i), i(i), j(this->i) { } };
除非在i
初始化后對this->i
的求值進行排序,否則這將是無效的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.