Date: 2022-06-11
Reply-to: Justin Cooke
<jgc@cems.de>
Target audience: EWG, CWG
Make redundant empty angle brackets optional
Proposal: To make redundant empty angle brackets optional for class template argument lists.
Motivation. Additional template parameters with default arguments can be added to a class template declaration in a header file without breaking code that uses the template. For example, early versions of std::vector took just one parameter, the value type; the allocator parameter was added later, with a default argument. However, that upgrade pathway is currently only open where there is already at least one template parameter. It is not currently possible to replace a non-template class declaration by a class template, even with default arguments for all parameters, without breaking most uses of the class, because the syntax for using class templates requires empty angle brackets in most circumstances, even where their omission would not result in ambiguity. Since the introduction of CTAD (in C++17), angle brackets can be omitted when defining objects, but they are still required when declaring pointers, references, arrays, external objects, function parameters, class members, base classes, or template type parameters. The following examples illustrate the current situation:
template <typename T = int> class C {};
C c; //OK (1)
extern C x; //error: need C<>
C *p; //error: need C<>
C a[2]; //error: need C<>
C &r = c; //error: need C<>
struct S { C c; }; //error: need C<>
struct D : C {}; // error: need C<>
std::vector<C> v; // error: need C<>
void foo(C c); // error: need C<>
The empty angle brackets are currently optional only in case (1). No ambiguity would arise from making them optional in all the above cases, because names of class or variable templates must be unique within a scope (13.1 Note 5). This change will allow class library maintainers to upgrade existing class definitions to templates without breaking user code.
Effect on existing code: None. Code using the proposed feature is ill-formed under C++20 and earlier standards.
Note: Empty angle brackets will still be required to disambiguate invocations of function templates from functions with the same name (13.10.2), and to denote empty template parameter lists, which are required to disambiguate explicit full specialization declarations (13.9.4) from explicit instantiation declarations (13.9.3).
Wording: (edits to N4910)
13.4.1 [temp.arg.general]
…
5 When
template argument packs or default template-arguments are
used, or template arguments are deduced
(13.10.3), a template-argument list
can be empty. In that case the empty <> brackets may be omitted shall still be used as the template-argument-list unless needed to disambiguate an invocation of a function
template specialization from an invocation of a non-template function with the
same name (13.10.2).
[Example 5 :
template<class T = char> class String;
String<>* p; // OK, String<char>
String* q; // syntax error
OK, empty brackets <>
omitted
template<class ... Elements> class Tuple;
Tuple<>* t; // OK, Elements is empty
Tuple* u; // syntax error
OK, empty brackets <>
omitted
—end example]
Two subsequent mentions (13.9.3 para 8, and 13.10.2 para 4) of the option to omit empty angle brackets become redundant under this proposal. If this redundancy grates, the repetitions can be deleted.