Reputation: 133112
class C
{
public:
C() : arr({1,2,3}) //doesn't compile
{}
/*
C() : arr{1,2,3} //doesn't compile either
{}
*/
private:
int arr[3];
};
I believe the reason is that arrays can be initialized only with =
syntax, that is:
int arr[3] = {1,3,4};
Note that I do not want to use std::array
or another container to solve this problem.
Upvotes: 125
Views: 229207
Reputation: 4725
This worked for me using C++17 on Windows:
File A.h
:
class A
{
private:
float arrayVar[3];
}
File A.cpp
:
A::A() : arrayVar{ 0.0f, 0.0f, 0.0f } { }
Upvotes: 1
Reputation: 1762
I found this question very useful, but found no example for the case when the member array element is an object without default constructor and with deleted copy/move constructors. In other words the example that initializes the member array without unnecessary object copy.
For example, with a following class A:
class A {
public:
int v;
A(int v) : v(v) { }
A() = delete;
A(A &&) = delete;
A(const A &) = delete;
A &operator =(A &&) = delete;
A &operator =(const A &) = delete;
};
In-place initialization with non-default constructor would look like:
class B {
public:
A a[3];
B() : a { {1}, {2}, {3} } {}
};
Upvotes: 3
Reputation: 145429
C++98 doesn't provide a direct syntax for anything but zeroing (or for non-POD elements, value-initializing) the array. For that you just write C(): arr() {}
.
I thing Roger Pate is wrong about the alleged limitations of C++0x aggregate initialization, but I'm too lazy to look it up or check it out, and it doesn't matter, does it? EDIT: Roger was talking about "C++03", I misread it as "C++0x". Sorry, Roger. ☺
A C++98 workaround for your current code is to wrap the array in a struct
and initialize it from a static constant of that type. The data has to reside somewhere anyway. Off the cuff it can look like this:
class C
{
public:
C() : arr( arrData ) {}
private:
struct Arr{ int elem[3]; };
Arr arr;
static Arr const arrData;
};
C::Arr const C::arrData = {{1, 2, 3}};
Upvotes: 39
Reputation: 507343
- How can I do what I want to do (that is, initialize an array in a constructor (not assigning elements in the body)). Is it even possible?
Yes. It's using a struct that contains an array. You say you already know about that, but then I don't understand the question. That way, you do initialize an array in the constructor, without assignments in the body. This is what boost::array
does.
Does the C++03 standard say anything special about initializing aggregates (including arrays) in ctor initializers? Or the invalidness of the above code is a corollary of some other rules?
A mem-initializer uses direct initialization. And the rules of clause 8 forbid this kind of thing. I'm not exactly sure about the following case, but some compilers do allow it.
struct A {
char foo[6];
A():foo("hello") { } /* valid? */
};
See this GCC PR for further details.
Do C++0x initializer lists solve the problem?
Yes, they do. However your syntax is invalid, I think. You have to use braces directly to fire off list initialization
struct A {
int foo[3];
A():foo{1, 2, 3} { }
A():foo({1, 2, 3}) { } /* invalid */
};
Upvotes: 68
Reputation: 27023
Workaround:
template<class T, size_t N>
struct simple_array { // like std::array in C++0x
T arr[N];
};
class C : private simple_array<int, 3>
{
static simple_array<int, 3> myarr() {
simple_array<int, 3> arr = {1,2,3};
return arr;
}
public:
C() : simple_array<int, 3>(myarr()) {}
};
Upvotes: 9
Reputation:
In C++03, aggregate initialization only applies with syntax similar as below, which must be a separate statement and doesn't fit in a ctor initializer.
T var = {...};
Upvotes: 4