Инициализация массива указателей на структуры в Stack Overflow

Инициализация массива указателей на структуры в C может быть выполнена с использованием составных литералов.

typedef struct {
int a;
int b;
} s;

В С:

s *ptrArray[] = {
&(s){
.a = 1,
.b = 2
},
&(s){
.a = 4,
.b = 5
}
};

Как это можно сделать в C ++?

Я также видел разницу в инициализации структур в C ++ без использования составных операторов:

s s1 = { a: 7, b: 8 };

2

Решение

Во-первых, инициализация чего-либо по адресу временного значения кажется чрезвычайно подозрительной, в том числе и в Си. Вы уверены, что это действительно? Хммм. В любом случае, компилятор C ++ действительно не позволит вам сделать это.

Что касается указанной вами строки инициализации (named-field) C ++ — она ​​на самом деле нестандартная, это расширение GNU C ++, и вы не можете на нее полагаться.

Вы могли бы сделать это:

struct s { int a, b; };

int main() {
s data[] = { { 1, 2 }, { 4, 5 } };
// instead of ptrArray[i], use &(data[i])
}

Это компилируется просто отлично. Но — более C ++ версия этого кода будет:

#include <array>

struct s { int a, b; };

int main() {
std::array<s, 2> data { s{ 1, 2 }, s{ 4, 5 } };
// instead of ptrArray[i], use &(data[i]),
// or use iterators, or ranged for loops
}

Почему вы хотите использовать std::array? Вот одно объяснение из преимуществ. На самом деле, вы могли бы сделать немного лучше и повторить меньше с:

int main() {
auto data = make_array(s{ 1, 2 }, s{ 4, 5 });
// instead of ptrArray[i], use &(data[i]),
// or use iterators, or ranged for loops
}

make_array функция взята из Вот; у вас также есть std::experimental::make_array(), но это еще не стандартизировано.

Если вы хотите добавить или удалить элементы из data во время выполнения вы можете переключиться на использование std::vector:

#include <vector>

struct s { int a, b; };

int main() {
std::vector<s> data { s{ 1, 2 }, s{ 4, 5 } };
// instead of ptrArray[i], use &(data[i]),
// or use iterators, or ranged for loops
}
3

Другие решения

Причиной сбоя инициализации является то, что вы пытались инициализировать массив указателей для структурирования по адресу числовых литеральных констант. Такой же как:

#define A 5
int b = &A;    /* NOT HAPPENING */

(вы не можете взять адрес 5)

Вы можете решить вашу проблему, просто инициализируя массив s вместо массив указателей в sНапример:

    s ptrarr[] = { {1, 2}, {4, 5} };

С этим изменением ваш массив будет инициализироваться нормально, например,

#include <iostream>

typedef struct {
int a;
int b;
} s;

int main (void) {

s ptrarr[] = { {1, 2}, {4, 5} };
int cnt = 0;

for (auto& i : ptrarr)
std::cout << "ptrarr[" << cnt++ << "] : " << i.a << ", " << i.b << "\n";

}

Пример использования / Вывод

$ ./bin/ptrarrystruct
ptrarr[0] : 1, 2
ptrarr[1] : 4, 5
1

По вопросам рекламы [email protected]