Скобки вокруг скалярного инициализатора при использовании массива структуры в структуре

Я пытаюсь сделать простое меню. Для этого я хочу использовать структуру, которая является меню и содержит массив структур пунктов меню.

Главное меню - Программы - Настройки

Пункты меню содержат некоторую дополнительную информацию, такую ​​как обратный вызов.

struct menu_t {
    char* text;
    const uint32_t num;
    const struct menuitem_t *contents[MAX_MENU_CONTENTS];
};

struct menuitem_t {
    char* text;
    uint8_t type;
    void (*callback)(void);
}

static const struct menu_t mainMenu[] = {
    .name = "Main Menu",
    .num = 3,
    .contents = {
        {
        .text = "Programms",
        .type = MENU_SUB,
        .callback = 0,
        },
        {
        .text = "Settings",
        .type = MENU_SUB,
        .callback = 0,
        }
    }
};

Но я всегда получаю ошибку

фигурные скобки вокруг скалярного инициализатора для типа 'const menuitem_t*'


person Julian    schedule 01.08.2019    source источник
comment
contents — это массив указателей. Ты уверен, что хочешь этого?   -  person NathanOliver    schedule 01.08.2019
comment
contents — это массив указателей на menuitem_t, а не массив menuitem_t.   -  person KamilCuk    schedule 01.08.2019
comment
Отсутствие массива указателей вызвало у меня ошибку, но теперь, похоже, он компилируется без ошибок. Спасибо   -  person Julian    schedule 01.08.2019
comment
Это больше похоже на C, чем на C++, особенно из-за назначенных инициализаторов...   -  person Aconcagua    schedule 01.08.2019


Ответы (2)


... при использовании массива структуры в структуре

У вас нет массива структур. У вас есть массив указателей для структуры.

Чтобы создать N объектов, вам нужен массив этих объектов. Например, в этом случае:

static const struct menuitem_t menu_items[MAX_MENU_CONTENTS] {
    {
    .text = "Programms",
    .type = MENU_SUB,
    .callback = 0,
    },
    {
    .text = "Settings",
    .type = MENU_SUB,
    .callback = 0,
    },
};

Если вы не хотите хранить эти объекты в классе, вы можете инициализировать указатели на объекты в этом массиве:

static const struct menu_t mainMenu[] = {
    .name = "Main Menu",
    .num = 3,
    .contents = {
        menu_items + 0,
        menu_items + 1,
    },
};

Другие проблемы с вашей программой:

  • menu_t не имеет члена .name, но вы пытаетесь его инициализировать. Вы имели в виду .text?
  • Назначенные инициализаторы еще не являются частью какого-либо выпущенного стандарта C++. Они будут представлены в грядущей версии C++20.
  • char* нельзя инициализировать строковым литералом (начиная с C++11; до этого преобразование устарело), ​​потому что строковые литералы в C++ константны. Либо измените элементы на const char*, либо используйте изменяемые массивы символов.
person eerorika    schedule 01.08.2019
comment
Большое спасибо. Я буду использовать это так. Я знаю, что char* больше нельзя инициализировать строками, но у меня не было времени исправить это везде, я сделаю это позже. - person Julian; 01.08.2019

Если это действительно код C++17, то у вас много опечаток.

Например, структура menu_t не содержит элемента данных name.

Элемент данных contents представляет собой массив указателей. Однако он не инициализируется указателями.

В C++ строковые литералы имеют типы постоянного массива символов. Поэтому соответствующие указатели в ваших структурах, которые инициализируются строковыми литералами, должны иметь квалификатор const.

Если вы инициализируете агрегат, то его список инициализаторов должен быть заключен в фигурные скобки.

Ниже приведена демонстрационная программа, показывающая, как можно инициализировать ваши структуры.

#include <iostream>
#include <cstdint>

enum { MENU_SUB };
const size_t MAX_MENU_CONTENTS = 2;

struct menuitem_t;

struct menu_t {
    const char * name;
    const uint32_t num;
    const menuitem_t *contents[MAX_MENU_CONTENTS];
};

struct menuitem_t {
    const char *text;
    uint8_t type;
    void (*callback)(void);
};

static const struct menu_t mainMenu[] = 
{
    {
        .name = "Main Menu",
        .num = 3,
        .contents = 
        {
            new menuitem_t 
            {
                .text = "Programms",
                .type = MENU_SUB,
                .callback = nullptr,
            },
            new menuitem_t 
            {
                .text = "Settings",
                .type = MENU_SUB,
                .callback = nullptr,
            }
        }            
    }
};

int main()
{
}
person Vlad from Moscow    schedule 01.08.2019