Initializing Constant Static Array In Header File

后端 未结 6 1956
春和景丽
春和景丽 2020-12-13 12:31

I have just found out that the following is not valid.

//Header File
class test
{
    const static char array[] = { \'1\', \'2\', \'3\' };
};
相关标签:
6条回答
  • 2020-12-13 13:05

    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:

    • No need for a cpp file
    • You can do range checking if you want to
    • You avoid having to worry about the static initialization fiasco
    0 讨论(0)
  • 2020-12-13 13:08

    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.

    0 讨论(0)
  • 2020-12-13 13:08
    //Header File 
    class test 
    { 
        const static char array[];
    }; 
    
    // .cpp
    const char test::array[] = { '1', '2', '3' }; 
    
    0 讨论(0)
  • 2020-12-13 13:10

    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.

    0 讨论(0)
  • 2020-12-13 13:18

    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

    0 讨论(0)
  • 2020-12-13 13:25

    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) {}
    };
    
    0 讨论(0)
提交回复
热议问题