標籤:

std::array 是被編譯器特別對待的嗎?

std::array 是不是和 std::initializer_list 一樣都是被編譯器特別對待的?

因為 VS2015 的 std::array 源碼中它沒有任何構造,卻可以通過參數列表初始化:

std::array& = {0};

並且 std::array& = {0,1}; 在編譯期會提示參數列表數據過多。

是否能自己實現這樣的效果?std::array 是被編譯期特別對待的嗎?


從如何用initializer_list初始化一個C數組? - C++ 這個問題可以知道,題主自己實現的Array把內部的數組成員設為private,而且打算自定義構造函數。

但是std::array並不是一個普通的類,它是一個聚合體(aggregate)。

------------------------------------------------------------------------------------------------------

C++標準§ 23.3.2.2 array constructors, copy, and assignment:

The conditions for an aggregate shall be met. Class array relies on the implicitly-declared special member functions to conform to the container requirements table in 23.2. In addition to the requirements specified in the container requirements table, the implicit move constructor and move assignment operator for array require that T be MoveConstructible or MoveAssignable, respectively.

標準規定array必須是個聚合體,所有特殊成員函數都是隱式聲明的。

那為什麼聚合體就可以不需要構造函數就能直接使用initializer_list構造呢?

------------------------------------------------------------------------------------------------------

C++標準§ 8.5.1 Aggregates:

第1條:

An aggregate is an array or a class with no user-provided constructors, no private or protected non-static data members, no base classes, and no virtual functions.

第2條:

When an aggregate is initialized by an initializer list, as specified in 8.5.4, the elements of the initializer list are taken as initializers for the members of the aggregate, in increasing subscript or member order. Each member is copy-initialized from the corresponding initializer-clause. If the initializer-clause is an expression and a narrowing conversion is required to convert the expression, the program is ill-formed.

[ Note: If an initializer-clause is itself an initializer list, the member is list-initialized, which will result in a recursive application of the rules in this section if the member is an aggregate. —end note ]

[ Example:

struct A {
int x;
struct B {
int i;
int j;
} b;
} a = { 1, { 2, 3 } };

initializes a.x with 1, a.b.i with 2, a.b.j with 3. —end example ]

第6條:

An initializer-list is ill-formed if the number of initializer-clauses exceeds the number of members or elements to initialize.

[ Example:

char cv[4] = { "a", "s", "d", "f", 0 }; // error

is ill-formed. —end example ]

從以上三條可以看出:

  1. 題主的Array類有自定義的構造函數和私有成員,所以它不是聚合體。
  2. 標準規定使用含有過多元素的initializer_list初始化一個聚合體是不合法的。


並沒有被特別對待。std::array 能這樣是因為它是一個聚合體(aggregate):沒有自定義的構造函數、非靜態成員都是 public 而且沒有用聲明時初始化、沒有虛函數的類。


推薦閱讀:

C語言編譯器為什麼能夠用C語言編寫?
為什麼總有人追求 one-pass compiler?
c++為什麼需要虛函數表?
現在編譯器處理那種「用換行代替分號」的語句邏輯是怎麼做的?

TAG:C | 編譯器 |