C++17(4) : 聚合初始化

一、C++17中聚合的定义

    1、任意数组都被称为聚合。

    2、具有以下特点的类、结构体或者是共用体:

        -没有用户声明的构造函数或者被explict修饰的构造函数。

        -没有using Base::Base()这种的构造函数。    

struct Data{
};

struct D: public Data{
    using Data::Data;
};

        -没有private、protected的非静态数据成员。

        -没有虚函数。

        -没有virtual、private、protected的基类。

    C++ 17提供了std::is_aggregate::value 来判断T类型是否是聚合结构(value == True 为聚合)。或者使用辅助函数std::is_aggregate_v来判断。

 

二、聚合的初始化

struct B{
    int i = 1;
    std::string str = "Hello Aggregate";
};

struct D: public B{
    double d = 10;
};

int main(){
    //聚合初始化。
    D d{{100, "Hello World."}, 1};
    std::cout << d.i << " " << d.str << " " << d.d << std::endl;

    return 0;
}

    在c++17前,必须实现出构造函数,才能使用D d{100, "Hello World." , 1}来初始化,在C++17中,可以直接使用上述方法来初始化。

 

1.几种初始化方式的对比

struct B{
    int i;
    std::string str;
};

struct D: public B{
    double d;
};

int main(){
    D a{};         //使用0初始化所有元素。
    D b{{100}};    //如同 {{100,''}, 0}
    D c{{}, 1};    //如同 {{0,''}, 1}
    D d;           //基本类型的值未指定

    std::cout << "D a{}      : " << a.i << " " << a.str << " " << a.d << std::endl;
    std::cout << "D b{{100}} : " << b.i << " " << b.str << " " << b.d << std::endl;
    std::cout << "D c{{}, 1} : " << c.i << " " << c.str << " " << c.d << std::endl;
    std::cout << "D d        : " << d.i << " " << d.str << " " << d.d << std::endl;

    return 0;
}

输出结果:

D a{}      : 0  0
D b{{100}} : 100  0
D c{{}, 1} : 0  1
D d        : 3735552  nan

 

2、聚合与static_cast

template
struct D : std::string, std::complex
{
    std::string data;
};

int main(){

    D s{{"hello"}, {4.5,6.7}, "world"};                      // OK since C++17
    std::cout << s.data << std::endl;                               // outputs: "world"
    std::cout << static_cast(s) << std::endl;          // outputs: "hello"
    std::cout << static_cast>(s) << std::endl;  // outputs: (4.5,6.7)
    return 0;
}

3、向前不兼容

struct Derived;

struct Base {
    friend struct Derived;
private:
    Base() {}
};

struct Derived : Base {};

int main()
{
    // C++17中是编译出错的,因为Dericed不满足聚合的特点,不能这样初始化.
    // 但是在C++14中,这是可以的。
    Derived d1{};   
    //下面这样写是可以的,只不过基本类型的数据成员是不确定的值。
    Derived d2;      
}

 

你可能感兴趣的:(C++)