user174084
user174084

Reputation: 1107

Initializing Constant Static Array In Header File

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?

Upvotes: 52

Views: 105497

Answers (6)

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.

Upvotes: 2

Jim Hunziker
Jim Hunziker

Reputation: 15380

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) {}
};

Upvotes: 0

JKD
JKD

Reputation: 663

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:

Upvotes: 39

lz96
lz96

Reputation: 2998

Now, in C++17, you can use inline variable

How do inline variables work?

A simple static data member(N4424):

struct WithStaticDataMember {
  // This is a definition, no out­of­line 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

Upvotes: 14

Mike Seymour
Mike Seymour

Reputation: 254461

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.

Upvotes: 58

peterchen
peterchen

Reputation: 41106

//Header File 
class test 
{ 
    const static char array[];
}; 

// .cpp
const char test::array[] = { '1', '2', '3' }; 

Upvotes: 21

Related Questions