Initialize a Const Array in a Class Initializer in C++

initialize a const array in a class initializer in C++

Like the others said, ISO C++ doesn't support that. But you can workaround it. Just use std::vector instead.

int* a = new int[N];
// fill a

class C {
const std::vector<int> v;
public:
C():v(a, a+N) {}
};

Initialization of const array in C++

The only way I can conceive doing this while staying out of the C++11 initializer list realm is to bury it in a struct wrapper and value-initialize it in your construct-initializer list:

#include <iostream>
using namespace std;

struct ArrayWrap
{
int content[4];
int& operator [](size_t n) { return content[n]; }
int operator [](size_t n) const { return content[n]; }
};

static const ArrayWrap content = { {1,2,3,4} };


struct MyObj
{
const ArrayWrap arrwrap;

MyObj() : arrwrap(content) {}
};

int main(int argc, char *argv[])
{
MyObj obj;
for (int i=0;i<4;++i)
cout << obj.arrwrap[i] << ' ';
cout << endl;

return EXIT_SUCCESS;
}

Output

1 2 3 4

It is common in C to bury fixed arrays in structures when returning them from functions by value, and in this case I'm simply exploiting the default copy-ctor of the wrapper struct as-generated by the C++ compiler.

Probably not the ideal solution for what you want, but it does work, and compiles under C++98.

c++ how to initialize const elements of an array

How about this?

#include <array>
typedef std::array<int, 255> Array;

const Array array = generateData();

Array generateData(){
Array a;
for(int i = 0; i < a.size(); i++) {
initializeSomehowTo(a[i]);
}
return a;
}

initializing a const array in the constructor

Use std::array:

struct A {
A(std::array<int, 5> const& arr)
: arr_(arr)
{}

std::array<int, 5> const arr_;
}

const array class member initialization

Make it static?

class GameInstance{
enum Signs{
NUM_SIGNS = 3};
static const int gameRulesTable[2][2];
public:
explicit GameInstance(){};
};

...in your cpp file you would add:
const int GameInstance::gameRulesTable[2][2] = {{1,2},{3,4}};

Array initialization use const variable in C++

Because the guys in the C++ committee decided so.

The technical reason is that the first expression that is used to initialize size is a constant expression and it can be computed during compilation. This means that the compiler can also know how big the array is going to be and the allocation (in this case "reservation" may be a more appropriate term) can be done at compile time.

In the second case instead the expression is not a constant expression (given the C++ definition) and this revervation is not possible.

The fact that in the second case the value is indeed fixed by the time size is initialized is totally irrelevant. The rules are base on the "kind of expression" and the second expression uses mutable variables and thus the compiler considers it non-constant.

Allowing the second form for compile-time initialization would require a flow analysis because it would need to distinguish between

int a = 2;
const int size = a;

and

int a = foo();
const int size = a;

where the expression involving size is indeed identical.

Initialization of const array of const in a template C++ class

Based on the update to your question you can still handle the initialization cleanly and reduce the code further than what I previously proposed. Since you know the data is writable you can use const_cast and do the initialization in the constructor.

template <typename T>
class InitConst
{
public:
const T* const v1;
const T* const v2;
const T* const v3;

InitConst(T a1, T a2, T a3, int n)
: v1( new T[n] ), v2( new T[n] ), v3( new T[n] )
{
T* t1 = const_cast<T*>(v1);
T* t2 = const_cast<T*>(v2);
T* t3 = const_cast<T*>(v3);

// do intialization here
}
};





[NOTE: The following solution is not usable based on comments from the OP]

It would be better to have init assist in the initialization of a single member variable at a time rather than all three. This would reduce the code significantly and eliminate the need for the static variable which will need to be defined for each type of T used with InitConst. You could also change init to be static to prevent the accidental use of member variables that have not been initialized.

template <typename T>
class InitConst
{
public:
const T* const v1;
const T* const v2;
const T* const v3;

InitConst(T a1, T a2, T a3, int n)
: v1( init(a1,n) ), v2( init(a2,n)), v3(init(a3,n))
{ }

private:
static const T* init (T a, int n)
{
T* v = new T[n];
// populate "v" from "a"
return v
}
};

C++11 Initializing class static const array

test.cpp:9:66: error: 'constexpr' needed for in-class initialization
of static d ata member 'const Fruit::Value Fruit::VALUES [4]' of
non-integral type [-fpermis sive]

Compiler told what is missing:

class Fruit
{
public:
enum Value { APPLE, ORANGE, BANANA, NONE };
static constexpr Value VALUES[4] = { APPLE, ORANGE, BANANA, NONE };
// ^^^^^^^^^
...
};

cc1l4Xgi.o:test.cpp:(.text+0x1a): undefined reference to
`Fruit::VALUES'

To make linker happy, you must add this line somewhere in source files (not header file):

constexpr Fruit::Value Fruit::VALUES[4];

EDIT:
Since c++17 we have inline variables and each constexpr variable is inline, so in C++17 the problem is solved.



Related Topics



Leave a reply



Submit