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
How to Propagate Exceptions Between Threads
Is It Legal to Recurse into Main() in C++
Why Should I Declare a Virtual Destructor For an Abstract Class in C++
Demote Boost::Function to a Plain Function Pointer
Throwing Exceptions from Constructors
Const& , & and && Specifiers For Member Functions in C++
Non-Blocking Console Input C++
How to Properly Use Widechartomultibyte
Static_Assert Dependent on Non-Type Template Parameter (Different Behavior on Gcc and Clang)
Efficient String Concatenation in C++
Constexpr If and Static_Assert
How to Deal With Mutexes in Movable Types in C++
Initialize a Const Array in a Class Initializer in C++
Meaning of = Delete After Function Declaration
How to Check If a C++ String Is an Int