c++ - 聚合与非聚合结构/类

标签 c++ aggregate-type

我试图了解聚合类/结构/union 是什么:这是来自 C++ 标准:

An aggregate is an array or a class (Clause 9) with no user-provided constructors (12.1), no brace-or-equal-initializers for non-static data members (9.2), no private or protected non-static data members (Clause 11), no base classes (Clause 10), and no virtual functions (10.3).


所以我写了这个来测试:
struct NonAggregate{
    virtual void f()const&{} // virtual member function makes the struct non-aggregate
};

struct Bar{}; // aggregate
struct X{}; // aggregate

struct Foo : Bar, X{
   // Foo() = default; // if un-comment out makes Foo non-aggregate
   Foo& operator =(Foo const&){return *this;} // ok
   ~Foo(){} // ok
   int x_ = 0; // has an initializer. ? still aggregate?
   Bar b_{}; // has an initializer. still aggregate?

private:
    static double constexpr pi_ = 3.14;
};

double constexpr Foo::pi_; // definition needed- (although it has an in-class intializer) if Foo::pi_ used outside of the class

int main(){

    std::cout << std::boolalpha << "Foo is an aggregate type: " << std::is_aggregate<Foo>::value << '\n';

}
输出是:
Foo is an aggregate type: true
  • 那么为什么如果我默认合成的默认构造函数 Foo不再是一个聚合?只要我没有提供用户定义的?
  • 标准还说:no base classes (Clause 10)但我的结构从两个聚合结构继承乘法 BarX但仍然是 n 聚合??!
  • 标准说:no brace-or-equal-initializers for non-static data members (9.2)但我有非静态数据成员的初始值设定项 x_b_但是编译器还是会考虑Foo作为聚合结构?谢谢!

  • *P.S:我使用过 GCC 和 C++2a 标准

    最佳答案

    什么是聚合和什么不是聚合的规则在各种标准版本中发生了很大变化。这个答案简要强调了与 OP 的三个问题相关的变化。有关更详尽的段落,请参见例如The fickle aggregate ,其中介绍了这些不同的规则以及正确的标准(版本)引用。

    So why If I default the synthesized default constructor Foo is no more an Aggregate? As long as I've not provided a user-defined one?


    在 C++11 到 C++17 中,要求读取“无用户提供”构造函数,只要它们在第一次声明时被定义为显式默认或显式删除,它仍然允许声明构造函数。
    // Aggregate in C++11 through C++17. Not an aggregate in C++20.
    struct A {
        A() = default;  // user-declared, but not user-provided
    };
    
    // Aggregate in C++11 through C++17. Not an aggregate in C++20.
    struct B {
        B() = delete;  // user-declared, but not user-provided
    };
    
    // Never an aggregate.
    struct C {
        C();  // user-declared & user-provided
    };
    C::C() = default;
    
    从 C++20 开始,这个要求对“没有用户声明的构造函数”变得更加严格。

    Also the standard says: no base classes (Clause 10) but my struct inherits multiply from two aggregate structs Bar and X but still n Aggregate??!


    这是 C++11 和 C++14 中的规则。从 C++17 开始,它更宽松:

    1.4) no virtual, private, or protected base classes ([class.mi]).



    The standard says: no brace-or-equal-initializers for non-static data members (9.2) but I have initializers for non-static data members x_ and b_ but the compiler still consider Foo as an aggregate struct?? Thank you!


    此规则在 C++14 中被删除。

    关于c++ - 聚合与非聚合结构/类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68809603/

    相关文章:

    c++ - 如何将int转换为chrono毫秒

    c++ - 需要帮助编写双哈希实现的查找函数

    c++ - std::greater<int>()(100, 300),为什么它有效?

    c++ - 除了继承聚合结构之外,为什么结构不是空的,可以聚合初始化?

    c++ - 在位掩码中选择与选择器位图中的 1 位重叠的设置位跨度

    c++ - VS2015 + VTK 7.1.0 + Qt 5.8.0 运行来自 VTK 入口点失败的 Qt 示例