заключенный в скобки список инициализаторов - PullRequest
1 голос
/ 27 декабря 2010

при условии, что у меня есть объект, похожий на этот:

struct MenuDef
{
    int titleResourceId;

    struct MenuItemDef {
        char*               name;
        int                 value;
        SomeFunctionPtr     someFactory;
    } menuItems[10];
};

То есть инициализируется так:

const MenuDef m = {
    1,
    {
        {
            "zero",
            0,
            (SomeFunctionPtr) & MenuButton::factory,
        },
        {
            "one",
            1,
            (SomeFunctionPtr) & MenuButton::factory,
        },
        {
            "two",
            2,
            (SomeFunctionPtr) & MenuButton::factory,
        },
    }
};

Можно ли предположить, что m.menuItems[3].someFactory == 0 ?

например, в таком цикле:

for ( int i = 0; m.menuItems[i].someFactory != 0; ++i)

или мне нужно вставить последний элемент, чтобы отметить конец массива от руки, чтобы быть в безопасности?

...
        {
            "two",
            2,
            (SomeFunctionPtr) & MenuButton::factory,
        },
        {
            "",
            0,
            (SomeFunctionPtr) 0,
        },
...

Ответы [ 2 ]

4 голосов
/ 27 декабря 2010

Я полагаю, что это безопасно в соответствии с 8.5.1 / 7:

Если в списке меньше инициализаторов, чем элементов в агрегате, то каждый член, не инициализированный явно, должен иметь значение-инициализированный (8.5).

В качестве напоминания:

Инициализация значения объекта типа T означает:

  • , если Tявляется типом класса (раздел 9) с объявленным пользователем конструктором (12.1), тогда вызывается конструктор по умолчанию для T (и инициализация является некорректной, если у T нет доступного конструктора по умолчанию);
  • если T является типом класса без объединения без конструктора, объявленного пользователем, то каждый нестатический член данных и компонент базового класса в T инициализируется значением;
  • , если T являетсятип массива, тогда каждый элемент инициализируется значением;
  • в противном случае объект инициализируется нулями
2 голосов
/ 27 декабря 2010

Ответ на ваш вопрос зависит от языковой версии (C ++ 98 или C ++ 03) и, в C ++ 98, от некоторых деталей, которые вы не предоставили.А именно, что такое SomeFuncPtr?Это обычный указатель на функцию или указатель на функцию-член?

Если это указатель на функцию-член, то в спецификации языка C ++ 98 внутренний класс не является POD.Поскольку это класс не POD, остальные члены массива будут инициализированы по умолчанию, вызывая их конструкторы по умолчанию.Предоставленный компилятором конструктор по умолчанию для внутреннего класса ничего не делает, поэтому оставшиеся члены массива будут содержать мусор.

В версии спецификации языка C ++ 03 остальные члены массива инициализируются значением, что будетдействительно, инициализируйте нулем остальную часть массива, независимо от того, что является SomeFuncPtr.

Итак, если вы используете компилятор, совместимый с C ++ 03, у вас все хорошо.Если вы хотите быть обратно переносимыми к компиляторам C ++ 98, вы можете включить этот явный завершающий инициализатор (опять же, в зависимости от того, что SomeFuncPtr).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...