Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
430 views
in Technique[技术] by (71.8m points)

c++ - Can class template constructors have a redundant template parameter list in c++20

As far as I'm aware, the following code:

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

is well-formed, even though the <T> in the declaration of the constructor is redundant.

However, on gcc trunk (but not on gcc10.2), with -std=c++20 this gives an error:

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

The code compiles on clang trunk with -std=c++20. Is this a bug, or is this a breaking change in c++20 that is yet to be implemented in all compilers?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

There was a change, in fact. It's documented in the compatibility section of the C++20 draft.

[diff.cpp17.class]

2 Affected subclauses: [class.ctor] and [class.dtor]
Change: A simple-template-id is no longer valid as the declarator-id of a constructor or destructor.
Rationale: Remove potentially error-prone option for redundancy.
Effect on original feature: Valid C++ 2017 code may fail to compile in this International Standard. For example:

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
};

Specifically, the wording delta is this:

n4659 - C++17 standard draft - [class.ctor]

1 Constructors do not have names. In a declaration of a constructor, the declarator is a function declarator of the form

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

where the ptr-declarator consists solely of an id-expression, an optional attribute-specifier-seq, and optional surrounding parentheses, and the id-expression has one of the following forms:

  • in a member-declaration that belongs to the member-specification of a class but is not a friend declaration, the id-expression is the injected-class-name of the immediately-enclosing class;
  • in a member-declaration that belongs to the member-specification of a class template but is not a friend declaration, the id-expression is a class-name that names the current instantiation of the immediately-enclosing class template; or

n4861 - C++20 standard draft - [class.ctor]

1 A constructor is introduced by a declaration whose declarator is a function declarator ([dcl.fct]) of the form

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

where the ptr-declarator consists solely of an id-expression, an optional attribute-specifier-seq, and optional surrounding parentheses, and the id-expression has one of the following forms:

  • in a member-declaration that belongs to the member-specification of a class or class template but is not a friend declaration ([class.friend]), the id-expression is the injected-class-name ([class.pre]) of the immediately-enclosing entity or

As you can see, the wording changed. C++20 now requires the injected class name when declaring a constructor for a class template. S<T> is a simple template id that names a specialization. Inside a template, the injected class name is simply S.

This is part of addressing CWG 2237.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...