your programing

왜`std :: initializer_list`가 리터럴 유형으로 정의되지 않습니까?

lovepro 2020. 12. 31. 23:07
반응형

왜`std :: initializer_list`가 리터럴 유형으로 정의되지 않습니까?


이것은이 질문의 후속입니다 . constexpr initializer_list 객체를 선언하는 것이 합법적인가요? .

C ++ 14 이후로 std::initializer_list클래스에는 constexpr. 인스턴스를 초기화하는 것은 당연한 것 constexpr std::initializer_list<int> list = {1, 2, 3};같지만 Clang 3.5 list는 상수 표현식으로 초기화되지 않는다고 불평 합니다. dyp가 주석에서 지적했듯이std::initializer_list 리터럴 유형에 대한 요구 사항 은 사양에서 사라진 것 같습니다.

클래스를 초기화 할 수없는 경우 constexpr로 완전히 정의되는 이유는 무엇입니까? 표준에 대한 감독이며 향후 수정 될 예정입니까?


표준위원회 initializer_list는 문자 그대로의 유형 을 의도 한 것 같습니다 . 그러나 이것은 명시적인 요구 사항 인 것처럼 보이지 않으며 표준의 버그 인 것 같습니다.

§ 3.9.10.5에서 :

다음과 같은 경우 유형은 리터럴 유형 입니다
.-다음 속성을 모두 포함하는 클래스 유형 (Clause 9) :
--사소한 소멸자가있는 경우
--집계 유형 (8.5.1)이거나 최소한 복사 또는 이동 생성자가 아닌 하나의 constexpr 생성자 또는 생성자 템플릿
--모든 비 정적 데이터 멤버 및 기본 클래스는 비 휘발성 리터럴 유형입니다.

§ 18.9.1에서 :

namespace std {
  template<class E> class initializer_list {
  public:
    /* code removed */
    constexpr initializer_list() noexcept;
    // No destructor given, so trivial
    /* code removed */
  };
}

이것은 첫 번째 및 두 번째 요구 사항을 충족합니다.

세 번째 요구 사항은 다음과 같습니다.

§ 18.9.2 (강조 내)에서 :

유형의 객체는 유형의 객체 initializer_list<E>배열에 대한 액세스를 제공합니다 const E. [참고 : 한 쌍의 포인터 또는 포인터에 길이 를 더하면 initializer_list. initializer_list8.5.4에 지정된 초기화 목록을 구현하는 데 사용됩니다. 이니셜 라이저 목록을 복사해도 기본 요소는 복사되지 않습니다.
—end note]

따라서 구현의 private 멤버 initializer_list가 비 휘발성 리터럴 유형일 필요는 없습니다 . 그러나 그들은 한 쌍의 포인터 또는 포인터와 길이가 "명백한 표현"이라고 믿고 있다고 언급했기 때문에 누군가가 initializer_list.

아마 clang과 표준의 버그라고 말하고 싶습니다.

참조 URL : https://stackoverflow.com/questions/27496004/why-isnt-stdinitializer-list-defined-as-a-literal-type

반응형