클래스 템플릿 생성자가 C ++ 20에서 중복 템플릿 매개 변수 목록을 가질 수 있습니까?

Aug 21 2020

내가 아는 한 다음 코드 는 다음과 같습니다 .

template<typename T>
struct S {
    S<T>();
};

<T>생성자의 선언이 중복 되더라도 올바른 형식 입니다.

그러나 gcc 트렁크 (gcc10.2가 아님)에서는 -std=c++20오류가 발생합니다.

error: expected unqualified-id before ')' token
    3 |     S<T>();
                 ^

코드 와 연타 트렁크에 컴파일합니다 -std=c++20. 이것은 버그입니까, 아니면 아직 모든 컴파일러에서 구현되지 않은 C ++ 20의 주요 변경 사항입니까?

답변

7 StoryTeller-UnslanderMonica Aug 21 2020 at 05:45

사실 변화가있었습니다. C ++ 20 초안의 호환성 섹션에 문서화되어 있습니다.

[diff.cpp17.class]

2 영향을받는 하위 절 : [class.ctor] 및 [class.dtor]
변경 : simple-template-id는 더 이상 생성자 또는 소멸자의 선언자 ID로 유효하지 않습니다.
근거 : 중복성을 위해 잠재적으로 오류가 발생하기 쉬운 옵션을 제거합니다.
원래 기능에 미치는 영향 : 유효한 C ++ 2017 코드가이 국제 표준에서 컴파일되지 않을 수 있습니다. 예를 들면 :

template<class T>
struct A {
  A<T>();           // error: simple-template-id not allowed for constructor
  A(int);           // OK, injected-class-name used
  ~A<T>();          // error: simple-template-id not allowed for destructor
};

특히 델타라는 표현은 다음과 같습니다.

n4659 -C ++ 17 표준 초안- [class.ctor]

1 생성자에는 이름이 없습니다. 생성자의 선언에서 선언자는 다음 형식의 함수 선언자입니다.

ptr-declarator ( parameter-declaration-clause ) noexcept-specifier attribute-specifier-seq

여기서 ptr-declarator는 id-expression, 선택적 attribute-specifier-seq 및 선택적 둘러싸는 괄호로만 구성되며 id-expression은 다음 형식 중 하나를 갖습니다.

  • 클래스의 멤버 사양에 속하지만 friend 선언이 아닌 멤버 선언에서 id-expression은 즉시 포함되는 클래스의 삽입 된 클래스 이름입니다.
  • 클래스 템플릿의 멤버 사양에 속하지만 friend 선언이 아닌 멤버 선언에서 id-expression은 즉시 포함되는 클래스 템플릿의 현재 인스턴스화를 명명하는 클래스 이름입니다. 또는

n4861 -C ++ 20 표준 초안- [class.ctor]

1 생성자는 선언자가 다음 형식의 함수 선언자 ([dcl.fct]) 인 선언에 의해 도입됩니다.

ptr-declarator ( parameter-declaration-clause ) noexcept-specifier attribute-specifier-seq

여기서 ptr-declarator는 id-expression, 선택적 attribute-specifier-seq 및 선택적 둘러싸는 괄호로만 구성되며 id-expression은 다음 형식 중 하나를 갖습니다.

  • 클래스 또는 클래스 템플릿의 멤버 사양에 속하지만 친구 선언 ([class.friend])이 아닌 멤버 선언에서 id-expression은 주입 된 클래스 이름 ([class.pre])입니다. 즉시 닫는 엔티티의

보시다시피 문구가 변경되었습니다. C ++ 20은 이제 클래스 템플릿에 대한 생성자를 선언 할 때 삽입 된 클래스 이름이 필요합니다. S<T>전문화를 명명하는 간단한 템플릿 ID입니다. 템플릿 내에서 삽입 된 클래스 이름은 단순히 S.

이것은 CWG 2237 주소 지정의 일부입니다 .