user5534993
user5534993

Reputation: 600

How to initialize a member of array type which has no default constructor in C++98?

I would like to define an member which is an array of a type which can not have a default constructor. The array must contain the actual objects, not pointers. Dynamic memory allocation (new/delete) can not be used.

Apparently this is not trivially possible in C++98, as initializer lists are not available yet? What are the alternatives?

Here a MVP:

struct I {
    const bool b;
};

struct O {
    I a[2];

    O() : a{true, false} {}
} o;

Error message with GCC:

<source>: In constructor 'O::O()':
<source>:8:12: error: extended initializer lists only available with '-std=c++11' or '-std=gnu++11' [-Werror=c++11-extensions]
    8 |     O() : a{true, false} {}
      |            ^

Upvotes: -1

Views: 131

Answers (2)

user5534993
user5534993

Reputation: 600

Using the pointer and answer from @user12002570 combined with the answer from @Cheers and hth. - Alf I designed the following solution:

struct I {
    I(int (&a)[4]) : i(a) {}
    int (&i)[4];
};

struct O {

    int m[2][4]; // data for initialization

    struct Container {
        I a[2]; // to be initialized
    } array;

    static Container generateArray(int (&array)[2][4]){
        Container c = {array[0], array[1]};
        return c;
    }

    O() : array(generateArray(m)) {}
} o;

In this example the reference to a int[4] needs to be initialized when constructing I (in contrast to const bool in the question).

It wraps the member array to be initialized into a struct "Container". This container can be initialized within the constructor initialization list of the outer class O using a function (generateArray()). In this case the generator function takes a reference to a multi-dimensional array as argument.

This complies with clang and gcc.

In addition to previous answers this solution uses an initializer with automatic storage duration.

Upvotes: 1

Alan
Alan

Reputation: 1

In C++98, What are the alternatives?

One alternative is to add a static data member into class O and then use it to initialize a as shown below:

struct O {
   
    I a[2];  
    
    static I const data[2];
    O() : a(data){}
} ; 

I const O::data[2] = {true, false};
int main()
{   O o;
    std::cout << (o.a[0]).b << " " << (o.a[1]).b; //prints 1 0 as expected
}

Working demo

Upvotes: 1

Related Questions