Reputation: 16695
I try to compile very simple code:
struct T {
int a[3];
int b;
int c;
};
int main() {
const int as[3] = { 5, 6, 7, };
const T t {
as, 2, 3,
};
return 0;
}
But it gives me very strange errors:
t.cpp: In function 'int main()':
t.cpp:11:5: error: array must be initialized with a brace-enclosed initializer
};
^
As from what I understand the compiler wants me to initialize everything in one single place. How do I initialize fields separately and then use them during initiliazation the structure later?
Upvotes: 15
Views: 2352
Reputation: 9418
You can also do this, but it assumes your T t
data is not really const as I remove its constness with const_cast<>()
#include <cstdio>
#include <cstring>
#include <algorithm>
struct T {
int a[3];
int b;
int c;
};
int main() {
const int as[3] = { 5, 6, 7, };
const T t {
{0}, 2, 3,
};
memcpy( reinterpret_cast< void* >( const_cast< int* > ( t.a ) ),
reinterpret_cast< const void* >( as ),
std::min( sizeof t.a, sizeof as ) );
printf( "t.a: '%d, %d, %d'\n", t.a[0], t.a[1], t.a[2] );
return 0;
}
If you data T t
is not actually const, you can do it without the const_cast<>()
#include <cstdio>
#include <cstring>
#include <algorithm>
struct T {
int a[3];
int b;
int c;
};
int main() {
const int as[3] = { 5, 6, 7, };
T t {
{0}, 2, 3,
};
memcpy( reinterpret_cast< void* >( t.a ),
reinterpret_cast< const void* >( as ),
std::min( sizeof t.a, sizeof as ) );
printf( "t.a: '%d, %d, %d'\n", t.a[0], t.a[1], t.a[2] );
return 0;
}
I am adding the reinterpret_cast<>()
because memcpy()
requires a void*
function void * memcpy ( void * destination, const void * source, size_t num );
Copies the values of num bytes from the location pointed to by source directly to the memory block pointed to by destination. http://www.cplusplus.com/reference/cstring/memcpy/
I am also doing std::min( sizeof t.a, sizeof as )
to avoid override any data it should not in case the source array is way bigger than expected.
And finally, {0}
is initializing by default the destine array with zeros. It could also be {}
to not initialize anything and let the default values to be trash memory/random data.
References:
Upvotes: 0
Reputation: 2244
As from what I understand the compiler wants me to initialize everything in one single place.
This is because array types decay into pointer types and then the compiler tries to assign a pointer to an array type.
How do I initialize fields separately and then use them during initiliazation the structure later?
You can use pointer types in the structure (which I would not advise). Or you can use container classes instead (STL).
Upvotes: 2
Reputation: 10415
Arrays are neither copy-constructible nor copy-assignable. If you have access to C++11 and newer, you could use std::array
.
#include <array>
struct T {
std::array<int, 3> a;
int b;
int c;
};
int main() {
const std::array<int,3> as = { 5, 6, 7, };
const T t {
as, 2, 3,
};
return 0;
}
Otherwise you will have to roll a loop and copy the elements individually.
Upvotes: 22
Reputation: 234655
C++ arrays are not copy constructible, so compilation will fail. However,
struct T {
int a[3];
int b;
int c;
};
int main() {
const T t {
{5, 6, 7, }, 2, 3,
};
return 0;
}
is an alternative, although it does discard the explicit as
variable.
Reference: http://en.cppreference.com/w/cpp/concept/CopyConstructible
Upvotes: 11