When to Use the Brace-Enclosed Initializer (2023)

C++ error: Array must be initialized with a brace enclosed initializer

The syntax to statically initialize an array uses curly braces, like this:

int array[10] = { 0 };

This will zero-initialize the array.

For multi-dimensional arrays, you need nested curly braces, like this:

int cipher[Array_size][Array_size]= { { 0 } };

Note that Array_size must be a compile-time constant for this to work. If Array_size is not known at compile-time, you must use dynamic initialization. (Preferably, an std::vector).

When to use the brace-enclosed initializer?

I think the following could be a good guideline:

  • If the (single) value you are initializing with is intended to be the exact value of the object, use copy (=) initialization (because then in case of error, you'll never accidentally invoke an explicit constructor, which generally interprets the provided value differently). In places where copy initialization is not available, see if brace initialization has the correct semantics, and if so, use that; otherwise use parenthesis initialization (if that is also not available, you're out of luck anyway).

  • If the values you are initializing with are a list of values to be stored in the object (like the elements of a vector/array, or real/imaginary part of a complex number), use curly braces initialization if available.

  • If the values you are initializing with are not values to be stored, but describe the intended value/state of the object, use parentheses. Examples are the size argument of a vector or the file name argument of an fstream.

array must be initialized with a brace-enclosed initializer c++

In this declaration

Personne join_p{stoi(n),name,s};

the data member of the structure Personne is declared like

char nom[10];

that is it is an array,

But the array name used as an initializer is implicitly converted to a pointer to its first element.

So you are trying to initialize an array with a pointer.

You may not initialize an array with a pointer. You need to copy the array name into the array join_p.nom.

Pay attention to that the array name does not contain a string but it seems that the data member nom must contain a string.

(Video) C++ Initializing Variables (3 ways including Brace Initialization)

In any case this loop

for (int i = 0; i < nom.length(); i++){
name[i] = nom[i];

is unsafe because you can write outside the array name.

It would be better that initially the data member nom of the structure had the type std::string.

Also these statements

Personne join_p{stoi(n),name,s};
p = &join_p;

do not make a great sense because the pointer p is not used anywhere within or outside the function except this assignment.

C: Array initialization requires a brace-enclosed initializer list - simple code

When using char walk[10][10] = { 0 }; I get the compiler error "C: Array initialization requires a brace-enclosed initializer list".

That is your compiler being terribly anal-retentive.

The statement in question is perfectly legal C. It defines a 10x10 2-D array of char named walk where every element (of 100) is 0.

To comply with your compiler whims, use one of

char walk[10][10] = { { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* ..., */ { 0, 0, 0, 0, 0, 0, 0, 0, 0 } };
char walk[10][10] = { { 0 }, { 0 } };
char walk[10][10] = { { 0 } };
char walk[10][10] = { 0 }; // initial statement wrongly rejected by compiler

Even better (IMHO) would be to configure your compiler to accept legal code.

godbolt.org accepts your initial code

Automatic generation of a brace-enclosed initializer list in C++ using language features (NOT pre-processor directives)

Like this:

#include <array>
#include <memory>
#include <utility>

template <std::size_t ...I>
std::array<std::shared_ptr<int>, sizeof...(I)> foo(std::index_sequence<I...>)
return {(void(I), std::make_shared<int>())...};

std::array<std::shared_ptr<int>, 4> array_ = foo(std::make_index_sequence<4>());

Guaranteed copy elision from C++17 ensures that the array is constructed in place, and no extra moves happen.

(Video) no matching call to std::thread::thread(<brace-enclosed initializer list>)

The return statement expands to {(void(0), std::make_shared<int>()), (void(1), std::make_shared<int>())...}. void(...) is not strictly necessary, but Clang emits a warning otherwise.

But if it was my code, I'd write a more generic helper instead:

#include <utility>

template <typename R, typename N, typename F, N ...I>
[[nodiscard]] R GenerateForEach(std::integer_sequence<N, I...>, F &&func)
return {(void(I), func(std::integral_constant<N, I>{}))...};

template <typename R, auto N, typename F>
[[nodiscard]] R Generate(F &&func)
return (GenerateForEach<R, decltype(N)>)(std::make_integer_sequence<decltype(N), N>{}, std::forward<F>(func));


auto array_ = Generate<std::array<std::shared_ptr<int>, 4>, 4>([](auto){return std::make_shared<int>();});

While the lambda discards the index in this case, it often ends up being useful, especially given that in [](auto index){...}, index.value is constexpr.

c++ error: array must be initialized with a brace-enclosed initializer

You can't use C arrays like other variables or objects in many cases. You can't pass a C array by value to a function or return a C array from a function. It will decay to a pointer to the first element. Therefore std::array was introduced in C++. It does exactly what you expected from C arrays in your code:

#include <array>

constexpr int V = 4;

auto floydWarshall(std::array<std::array<int, V>, V> graph){
for (int k = 0; k < V; k++) {
for (int i = 0; i < V; i++) {
for (int j = 0; j < V; j++) {
if (graph[i][k] + graph[k][j] < graph[i][j])
graph[i][j] = graph[i][k] + graph[k][j];
return graph;

With std::array you can pass a copy of the array to the function and don't need to copy it manually. You can return a copy of the array instead of using dynamic memory allocation and pointers.

You use the function with

auto dist = floydWarshall(graph);

where graph has type std::array<std::array<int, V>, V>.

Initialize a class with brace-enclosed initializer list

Initializer lists are more appropriate for situations where the size of the list is dynamic. In your case, where the size of Vec is a template parameter (i.e. static), you're probably better off with variadic parameters:

template <unsigned C>
struct Vec

template<typename ... V>
Vec(V ... args)
static_assert(sizeof...(V) == C, "");

then these will work:

(Video) Classes Part 22 - Curly brace versus parenthesis and std::initializer_list | Modern cpp Series

Vec<3> myVec2;
myVec2 = {1, 2, 3};
Vec<3> myVec3 = {1,2,3};

But this one won't, as it explicitly requires an std::initializer_list:

Vec<3> myVec1{{1,2,3}};

brace-enclosed initializer list conversion error

The errors are narrowing conversions, which are never allowed in uniform initializers.

That's relevant because aggregate initialization existed all along and did not have that restriction. Now in C++11 world, aggregate initialization is just a form of uniform initialization, with ditto narrowing rules.

You should explicitly convert the respective values (checking that the conversion is safe!)


struct X { short i; };

int init = 42;
X x{init}; // not ok

Explicitly converting makes it ok:

X x{static_cast<short>(init)}; // ok

Why do brace-enclosed initializer lists not work for std::array

Here is working solution - you need double braces for arrays.

int main()
const vector<Widget> vw = {
{"vw1", {1,2,3}},
{"vw2", {1,2,3}} };
const array<Widget,2> aw = {{
{"aw1", {1,2,3}},
{"aw2", {1,2,3}} }};
const vector<Object> vo = {
{"vo1", {1,2,3}},
{"vo2", {1,2,3}} };
const array<Object,2> ao = {{
{"ao1", {1,2,3}},
{"ao2", {1,2,3}} }};
return 0;



std::array is a container that encapsulates fixed size arrays.
This container is an aggregate type with the same semantics as a struct holding a C-style array T[N] as its only non-static data member. Unlike a C-style array, it doesn't decay to T* automatically. As an aggregate type, it can be initialized with aggregate-initialization given at most N initializers that are convertible to T: std::array a = {1,2,3};.

Theoretical implementation (it is more complicated in reality)

template <typename T, size_t size> 
struct array
T data[size];

So first brace is to aggregate-initializate array object on its own, second brace to aggregate-initializate internal "legacy C style" array.

Related Topics

Error Lnk2038: Mismatch Detected for '_Msc_Ver': Value '1600' Doesn't Match Value '1700' in Cppfile1.Obj

(Video) Member Initializer Lists in C++ (Constructor Initializer List)

C++ Access Static Members Using Null Pointer

Shadowing Variables

":" (Colon) in C Struct - What Does It Mean

Labels in Gcc Inline Assembly

Why Istream Object Can Be Used as a Bool Expression

Why Are Rvalues References Variables Not Rvalue

C++ Compiling on Windows and Linux: Ifdef Switch

Difference Between Std::System_Clock and Std::Steady_Clock

How to Convert Std::Chrono::Time_Point to Calendar Datetime String with Fractional Seconds

Gcc Style Weak Linking in Visual Studio

End of File(Eof) of Standard Input Stream (Stdin)

Math-Like Chaining of the Comparison Operator - as In, "If ( (5<J<=1) )"

Create a Directory If It Doesn't Exist

Force Gcc to Notify About Undefined References in Shared Libraries

Inline Function Linkage

(Video) Learn C++ 11 in 20 Minutes - Part I

May I Take the Address of the One-Past-The-End Element of an Array

What Are the Rules for the "..." Token in the Context of Variadic Templates


1. C++Now 2018: Jason Turner “Initializer Lists Are Broken, Let's Fix Them”
2. When C++ Style Guides Contradict - Nicolai Josuttis - CppCon 2019
3. C++: Initialize without Constructor
(Cow Corporation)
4. CppCon 2018: Greg Falcon “Initialization, Shutdown, and constexpr”
5. C++17 - The Best Features - Nicolai Josuttis [ACCU 2018]
(ACCU Conference)
6. CS 121, Lecture 35a
(WVU Tech YouTube)
Top Articles
Latest Posts
Article information

Author: Msgr. Refugio Daniel

Last Updated: 01/03/2023

Views: 6012

Rating: 4.3 / 5 (54 voted)

Reviews: 93% of readers found this page helpful

Author information

Name: Msgr. Refugio Daniel

Birthday: 1999-09-15

Address: 8416 Beatty Center, Derekfort, VA 72092-0500

Phone: +6838967160603

Job: Mining Executive

Hobby: Woodworking, Knitting, Fishing, Coffee roasting, Kayaking, Horseback riding, Kite flying

Introduction: My name is Msgr. Refugio Daniel, I am a fine, precious, encouraging, calm, glamorous, vivacious, friendly person who loves writing and wants to share my knowledge and understanding with you.