【问题标题】:Aggregate list initialization with another aggregate object聚合列表初始化与另一个聚合对象
【发布时间】:2019-07-30 08:05:52
【问题描述】:

我有:

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}; 确实有效,但与以下类似:

DisplayConfig config{r, 32};

可能吗?

【问题讨论】:

  • 没有。对不起。这是不可能的。
  • 如果更改DisplayConfig 是一个选项,那么您可以让它从DisplayResolution 继承以保持config.width 并允许聚合初始化...

标签: c++ c++14 aggregate-initialization


【解决方案1】:

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

当通过初始化列表初始化此类聚合时,以下内容适用:

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

所以在下面的语句中:

DisplayConfig config{r, 32};

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

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

还有一个警告,因为DisplayConfig 类的depth 成员没有给定初始化器:

warning: missing initializer for member 'DisplayConfig::colorDepth' [-Wmissing-field-initializers]

【讨论】:

    猜你喜欢
    • 2020-03-18
    • 1970-01-01
    • 1970-01-01
    • 2020-02-03
    • 1970-01-01
    • 1970-01-01
    • 2017-07-01
    • 2017-02-27
    • 2015-04-24
    相关资源
    最近更新 更多