 <blockquote> <pre><code>std::vector&lt;int&gt; a{1,2,4}; </code></pre> </blockquote> <p>This is initializer-list initialization, not aggregate, because <code>vector</code> is not an aggregate — its data is stored on the heap. You need to have <code>#include &lt;initializer_list&gt;</code> for it to work, although that header is typically included from <code>&lt;vector&gt;</code>.</p> <blockquote> <pre><code>a = {1,2,4}; </code></pre> </blockquote> <p>This also goes through a function overloaded on <code>std::initializer_list</code>, and the semantics are the same as the function call:</p> <pre><code>a.assign( {1,2,4} ); </code></pre> <blockquote> <pre><code> int c[3]={1,4}; </code></pre> </blockquote> <p>This <em>is</em> aggregate initialization. However you cannot do <code>c = { 3, 5, 6 }</code> afterward, because the braced-init-lists may only be initializers for new variables, not operands to built-in expressions. (In a declaration, the <code>=</code> 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.)</p> <p>The answer to your final question is that there's no way to write the necessary <code>operator =</code> overload for "naked" arrays, because it must be a member function. The workaround is to use <code>std::copy</code> and a <code>std::initializer_list</code> object.</p>