qweruiop
qweruiop

Reputation: 3266

Correct way to initialize const member in C++03

I need to write some C++03 code for a legacy environment. The following code compiles but the compiler (g++ (SUSE Linux) 6.3.1 20170202 [gcc-6-branch revision 245119] ) complains.

Code:

typedef unsigned char Key[100];

class A {
public:
    const Key key1 {0x1};
    const Key key2;

    A(): key2({0x1}) {};
};

int main() {
    A a;
    return 0;
}

Compiler output:

test.cpp:6:24: warning: non-static data member initializers only available with -std=c++11 or -std=gnu++11
     const Key key1 {0x1};
                        ^
test.cpp:6:20: warning: extended initializer lists only available with -std=c++11 or -std=gnu++11
     const Key key1 {0x1};
                    ^
test.cpp:6:24: warning: extended initializer lists only available with -std=c++11 or -std=gnu++11
     const Key key1 {0x1};
                        ^
test.cpp: In constructor ‘A::A()’:
test.cpp:10:15: warning: extended initializer lists only available with -std=c++11 or -std=gnu++11
     A(): key2({0x1}) {};
               ^
test.cpp:10:20: warning: list-initializer for non-class type must not be parenthesized
     A(): key2({0x1}) {};

So what is the correct way (i.e. compliant with C++03) to initialize const array members?

Upvotes: 1

Views: 473

Answers (1)

Dietmar Kühl
Dietmar Kühl

Reputation: 153810

C++11 introduced the ability to initialize array members in the initializer list. This feature is needed to initialize array elements to a specific value other than zero. Since arrays can't be copied, providing an initialized arrays to copy from also doesn't work.

However, what does work is to wrap the array with a struct and to initialize a const member by copying such a struct. For example:

template <int Size>
struct array {
    unsigned char value[Size];
};
typedef array<100> Key;
class A {
    Key const key1;
    Key const key2;
    static Key make_key() {
        Key rc = Key();
        rc.value[0] = 0x1;
        // whatever else
        return rc;
    }
public:
    A(): key1(make_key()), key2(make_key()) {}
};

The initialization in make_key() merely resembles the initialization in the example (the first element initialized to 0x1, all others to zero). Clearly, it can do do whatever else is needed, probably based on arguments forwarded from the constructor.

Upvotes: 1

Related Questions