I have just found out that the following is not valid.
//Header File
class test
{
const static char array[] = { '1', '2', '3' };
};
Where is the best place to initialize this?
I have just found out that the following is not valid.
//Header File
class test
{
const static char array[] = { '1', '2', '3' };
};
Where is the best place to initialize this?
The best place would be in a source file
// Header file
class test
{
const static char array[];
};
// Source file
const char test::array[] = {'1','2','3'};
You can initialize integer types in the class declaration like you tried to do; all other types have to be initialized outside the class declaration, and only once.
You can always do the following:
class test {
static const char array(int index) {
static const char a[] = {'1','2','3'};
return a[index];
}
};
A couple nice things about this paradigm:
//Header File
class test
{
const static char array[];
};
// .cpp
const char test::array[] = { '1', '2', '3' };
Now, in C++17, you can use inline variable
A simple static data member(N4424):
struct WithStaticDataMember { // This is a definition, no outofline definition is required. static inline constexpr const char *kFoo = "foo bar"; };
In your example:
//Header File
class test
{
inline constexpr static char array[] = { '1', '2', '3' };
};
should just work
With constexpr
you must define the value on the header even in C++11
If you use constexpr
instead of const
, then this answer suggests that you not only can, but must, define on header even in C++11:
#include <cassert>
struct MyClass {
static constexpr int is[] = {1, 2, 3};
static constexpr int i = 1;
};
// TODO is this ever mandatory? Create example that fails on -std=c++11.
// Pretty sure never mandatory in C++17 https://stackoverflow.com/a/40959093/895245
// constexpr int MyClass::is[];
int main (void) {
assert(MyClass::is[0] == 1);
assert(&MyClass::is[0] == &MyClass::is[1] - 1);
assert(MyClass::i == 1);
assert(&MyClass::i == &MyClass::i);
}
Compile and run with:
g++-10 -ggdb3 -O0 -std=c++11 -Wall -Wextra -pedantic -o main.out main.cpp
./main.out
If instead you try:
struct MyClass {
static constexpr int is[];
};
constexpr int MyClass::is[] = {1, 2, 3};
compilation fails with:
main.cpp:4:26: error: ‘constexpr’ static data member ‘is’ must have an initializer
Tested on Ubuntu 20.04.
This is kind of an abuse of the system, but if you REALLY want to define it in the header file (and you don't have C++17), you can do this. It won't be a static member, but it will be a constant that only takes up storage per compilation unit (rather than per class instance):
(Put all of this code in the header file.)
namespace {
const char test_init_array[] = {'1', '2', '3'};
}
class test {
public:
const char * const array;
test() : array(test_init_array) {}
};