2

我有:

struct DisplayConfig {
    int width;
    int height;
    int colorDepth;
};

另一个聚合:

struct DisplayResolution {
    int width;
    int height;
};

我想我们他们喜欢:

DisplayResolution resolution{1920, 1080};
DisplayConfig config{r, 32};

哪个不起作用。

更改DisplayConfig为:

struct DisplayConfig {
    DisplayResolution resolution;
    int colorDepth;
};

会起作用,但改变DisplayConfig不是一种选择,访问 config.width也不再起作用。

DisplayConfig{r.width, r.height, 32};确实有效,但sintax类似于:

DisplayConfig config{r, 32};

可能的?

4

1 回答 1

2

不,鉴于您的情况,这是不可能的:“改变DisplayConfig不是一种选择”。该类DisplayConfig确实满足聚合条件(在 C++14 中),因为它没有用户提供的构造函数,没有私有或受保护的非静态数据成员,没有基类,也没有虚函数。

当通过初始化列表初始化这样的聚合时,以下内容适用:

8.5.1 聚合[dcl.init.aggr]
...
2当聚合由初始化列表初始化时,初始化列表的元素被视为聚合成员的初始化,按递增的下标或成员顺序。每个成员都是从相应的初始化子句复制初始化的。如果初始化子句是一个表达式,并且需要一个窄化转换来转换该表达式,则该程序是非良构的。[ 注意:如果一个初始化子句本身就是一个初始化列表,则该成员是列表初始化的,如果该成员是一个聚合,这将导致本节中的规则的递归应用。——尾注]

所以在下面的语句中:

DisplayConfig config{r, 32};

r被视为第一个成员的初始值设定项DisplayConfigis width。由于转换失败,这会导致错误:

error: cannot convert 'DisplayResolution' to 'int' in initialization
     DisplayConfig config{ r, 32 };
                             ^

和一个警告,因为类的depth成员DisplayConfig没有给出初始化程序:

warning: missing initializer for member 'DisplayConfig::colorDepth' [-Wmissing-field-initializers]
于 2019-03-08T12:19:58.523 回答