C ++ 20中的指定初始值设定项


25

我对c ++ 20功能之一(指定的初始化程序)有疑问(有关此功能的更多信息,请点击此处

#include <iostream>

constexpr unsigned DEFAULT_SALARY {10000};

struct Person
{
    std::string name{};
    std::string surname{};
    unsigned age{};
};

struct Employee : Person
{
    unsigned salary{DEFAULT_SALARY};
};

int main()
{
    std::cout << std::boolalpha << std::is_aggregate_v<Person> << '\n'; // true is printed
    std::cout << std::boolalpha << std::is_aggregate_v<Employee> << '\n'; // true is printed

    Person p{.name{"John"}, .surname{"Wick"}, .age{40}}; // it's ok
    Employee e1{.name{"John"}, .surname{"Wick"}, .age{40}, .salary{50000}}; // doesn't compile, WHY ?

    // For e2 compiler prints a warning "missing initializer for member 'Employee::<anonymous>' [-Wmissing-field-initializers]"
    Employee e2 {.salary{55000}}; 
}

此代码使用gcc 9.2.0和-Wall -Wextra -std=gnu++2a标志进行编译。

正如你可以在上面看到,这两个结构,PersonEmployee有总量,但是却初始化Employee使用指定的初始总量是不可能的。

有人可以解释一下为什么吗?


我不知道这是否可以解决您的问题,但您可能无法在这里继承公共信息struct Employee : public Person
skratchi.at


@GSerg好吧,嗯...我从来没有浪费任何想法,因为我每次使用publicprivate每次...谢谢
skratchi.at 19/11/15

您得到的确切错误是什么?
skratchi.at

2
@ skratchi.at struct默认情况下是公开继承的
idclev 463035818 '19

Answers:


15

根据C ++ 20标准(9.3.1汇总。第3页)

(3.1)—如果初始化列表是一个指定的初始化列表,则聚合应为类类型,每个指示符中的标识符应命名该类的直接非静态数据成员,以及聚合的显式初始化的元素是那些或包含这些成员的元素。

因此,您可能无法使用指定的初始化程序列表来初始化基类的数据成员。

改为使用通常的列表初始化,例如

Employee e1{ "John", "Wick", 40, 50000 };

要么

Employee e1{ { "John", "Wick", 40 }, 50000 };

@ Jarod42在注释中指出,您可以编写

Employee e1{ { .name{"John"}, .surname{"Wick"}, .age{40} }, 50000 };

在这种情况下,直接基类由指定的初始化器列表初始化,而Employe类整体由未指定的初始化器列表初始化。


3
或混合:Employee e1{ { .name{"John"}, .surname{"Wick"}, .age{40} }, 50000 };
Jarod42 '19

@ Jarod42是的,它可以编译。
弗拉德(Vlad),来自莫斯科,

5

您可能有几个来自不同基础的名称相同的字段,

因此,从逻辑上讲,您应该提供所需基础的名称,但是似乎没有办法。

// Invalid too:
Employee e1{.Person.name{"John"}, .Person.surname{"Wick"}, .Person.age{40}, .salary{50000}};
Employee e2{.Person{.name{"John"}, .surname{"Wick"}, .age{40}}, .salary{50000}};

另外,C ++指定的初始化比C的约束更多:

注意:乱序的指定初始化,嵌套的指定初始化,指定的初始化程序和常规初始化程序的混合以及数组的指定初始化在C编程语言中均受支持,但在C ++中是不允许的。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.