简体   繁体   中英

Aggregate Initialization - Vectors and Arrays

I know the following statements work

std::vector<int> a{1,2,4} --->A (Aggregate Initialization)

or the following statement(s)

std::vector<int> a;
a = {1,2,4};                ---->B  Variable already initialized. - Then aggregate initialization is called

However in case of Arrays

 int c[3]={1,4};  ---->C (1,4,0)

However the following is not allowed

int c[3]; 
c = {1,4};   ---->D

Now my question is why does B work and D doesnt ?

std::vector<int> a{1,2,4};

This is initializer-list initialization, not aggregate, because vector is not an aggregate — its data is stored on the heap. You need to have #include <initializer_list> for it to work, although that header is typically included from <vector> .

 a = {1,2,4};

This also goes through a function overloaded on std::initializer_list , and the semantics are the same as the function call:

a.assign( {1,2,4} );
 int c[3]={1,4};

This is aggregate initialization. However you cannot do c = { 3, 5, 6 } afterward, because the braced-init-lists may only be initializers for new variables, not operands to built-in expressions. (In a declaration, the = sign is just a notation for initialization. It is not the usual operator. Braced lists are specifically allowed by the grammar for assignment operators, but this usage is only valid with function overloading, which causes the list to initialize a new variable: the function parameter.)

The answer to your final question is that there's no way to write the necessary operator = overload for "naked" arrays, because it must be a member function. The workaround is to use std::copy and a std::initializer_list object.

As has been explained in other answers, the mechanism for this assignment is the vector's std::initializer_list assignment operator . This makes the following possible with brace enclosed initializer lists of arbitrary value, despite std::vector<int> not being an aggregate:

std::vector<int> a;
a = {1,2,4};       // OK, vector& operator=(std::initializer_list<T>)

However the following is not allowed

int c[3]; 
c = {1,4}; // Error: arrays are not assignable

This is because arrays are not assignable. If it were a different kind of aggregate, then this would work. For example,

struct Foo { int a, b, c; }; // aggregate
Foo f = {1, 2, 3};           // OK, aggregate initialization
f = { 1, 4 };                // OK

Here, fa , fb and fc are assigned the values 1, 4, 0 respectively.

Furthermore, non-aggregates can also be initialized and assigned-to with brace-enclosed initializer lists when they have (non- explicit ) constructors with a parameter list compatible with the elements of the list. For example,

struct Bar
{
  Bar(int a, int b, int c) : a(a), b(b), c(c) {} // non-aggregate 
  int a, b, c;
};

Bar b0 = {1, 2, 3}; // OK
Bar b1 = {1,2};     // Error: number of elements must be 3
b0 = {11, 22, 33}.  // Assignemnt OK

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM