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 anfstream
.
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.
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.
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));
}
Then:
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
{
Vec(){} template<typename ... V>
Vec(V ... args)
{
static_assert(sizeof...(V) == C, "");
//...
}
};
then these will work:
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!)
E.g.
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;
}
Why?
http://en.cppreference.com/w/cpp/container/array
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
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
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