【问题标题】:Why is std::is_aggregate<T> an aggregate?为什么 std::is_aggregate<T> 是一个聚合?
【发布时间】:2019-04-23 14:03:55
【问题描述】:

我一直认为std::is_samestd::is_voidstd::is_aggregate 之类的类型应该继承自std::integral_constant,或者更具体地说是继承自std::bool_constant

但是,聚合类不能有基类by definition,但是当我在std::is_aggregate_v&lt;T&gt; 中将这些类型用作T 时,我得到true。显然,它们不是源自std::bool_constant?

所以我的问题是:

为什么std::is_aggregate_v&lt;std::is_aggregate&lt;void&gt;&gt; 是正确的,至少对于 GCC 和 Clang?标准不是指定std::is_aggregate 是从std::bool_constant 派生的吗?如果不是,这是否意味着它将上述行的值保留为实现细节?

【问题讨论】:

  • en.cppreference.com/w/cpp/language/aggregate_initialization C++17 中允许使用非虚拟公共基类
  • 在您链接的页面上向下滚动;阅读整个页面;)
  • 是的,没有意识到链接的文本在多个答案中继续存在;)
  • @x432ph 阅读页面上的所有(或至少大部分)答案通常是个好主意;我们有一个一对多的问答模型是有原因的!

标签: c++ std c++17 typetraits


【解决方案1】:

但是,根据定义,聚合类不能有基类

这不再是真的。 [dcl.init.aggr]/1 将聚合定义为

聚合是一个数组或一个类

  • 没有用户提供的、显式的或继承的构造函数 ([class.ctor]),

  • 没有私有或受保护的非静态数据成员(子句 [class.access]),

  • 没有虚函数,并且

  • 没有虚拟、私有或受保护的基类 ([class.mi])。

[ 注意:聚合初始化不允许访问受保护和私有基类的成员或构造函数。 — 尾注 ]

不再像在 C++14 和更早版本中那样没有基类。只要它有一个现在允许的公共的、非虚拟的基类。这意味着类型特征现在被视为聚合,只要上述条件适用于它们

【讨论】:

  • std::is_aggregate 是 C++17 中的新功能,所以 OP 必须 使用它?
  • Pertinent link into the OP's source(他们没有读完)
  • @LightnessRacesinOrbit 哦,酷。我正要对最重要的答案发表评论以对其进行编辑,但如果有 C++17 特定答案,我将添加一个指向它的链接,以便更容易看到发生的变化。
  • 是的,到目前为止发布的所有标准都有答案 - 理想情况下,那里的 OP 应该重新接受
  • @LightnessRacesinOrbit 我已经更新了主要答案以指向它们以使其更加明显。
【解决方案2】:

自 C++17 起,具有非虚拟、非私有或受保护基的类是聚合:https://en.cppreference.com/w/cpp/language/aggregate_initialization

【讨论】:

    猜你喜欢
    • 2011-02-15
    • 1970-01-01
    • 2019-04-14
    • 2015-07-23
    • 1970-01-01
    • 1970-01-01
    • 2011-12-16
    • 2016-11-10
    • 2021-03-26
    相关资源
    最近更新 更多