C ++ 20의 지정된 이니셜 라이저


25

지정된 초기화 프로그램 인 C ++ 20 기능 중 하나에 대한 질문이 있습니다 (이 기능에 대한 자세한 정보는 here ).

#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 좋아, 그럼 ... 내가 사용하기 때문에, 그것에 대한 생각을 낭비 적이 public거나 private때마다 ... 감사 어쨌든
skratchi.at

당신이 얻는 정확한 오류는 무엇입니까 ??
skratchi.에서

2
@ skratchi.at struct기본적으로 공공의 상속
idclev 463,035,818

답변:


15

C ++ 20 표준 (9.3.1 집계, p. # 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

@ Jarod42 네, 컴파일됩니다.
모스크바에서 블라드

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 ++에서는 허용되지 않습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.