繁体   English   中英

用大括号括起来的初始化程序列表

[英]brace-enclosed initializer list

假设我有一个与此对象相似的对象:

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,
        },
...

我相信按照8.5.1 / 7的要求是安全的:

如果列表中的初始化程序少于聚合中的成员,则每个未显式初始化的成员都应进行值初始化(8.5)。

提醒一句 :

值初始化类型T的对象意味着:

  • 如果T是具有用户声明的构造函数(12.1)的类类型(第9节),则调用T的默认构造函数(如果T没有可访问的默认构造函数,则初始化格式不正确);
  • 如果T是没有用户声明的构造函数的非联合类类型,则T的每个非静态数据成员和基类组件都将被值初始化;
  • 如果T是数组类型,则每个元素都将值初始化;
  • 否则,将对象初始化为零

您问题的答案取决于语言版本(C ++ 98或C ++ 03),并且在C ++ 98中取决于您未能提供的某些详细信息。 即,什么是SomeFuncPtr 这是普通函数指针还是成员函数指针?

如果这是成员函数指针,则在C ++ 98版本的语言规范中,内部类不是POD。 由于它是一个非POD类,因此其余数组成员将通过调用其默认构造函数进行默认初始化。 编译器为内部类提供的默认构造函数不执行任何操作,因此数组的其余成员将包含垃圾。

在C ++ 03版本的语言规范中,其余的数组成员都进行了值初始化,这实际上将对数组的其余部分进行零初始化,而不管SomeFuncPtr是什么。

因此,如果您使用的是C ++ 03兼容的编译器,则可以。 如果您想向后移植到C ++ 98编译器,则可能需要包括该显式终止初始化程序(同样取决于SomeFuncPtr是什么)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM