<html>

<head>
<meta http-equiv=Content-Type content="text/html; charset=us-ascii">
<meta name=Generator content="Microsoft Word 15 (filtered)">
<style>
<!--
 /* Font Definitions */
 @font-face
	{font-family:"Cambria Math";
	panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
	{font-family:Calibri;
	panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
	{font-family:LMRoman9-Regular;
	panose-1:0 0 0 0 0 0 0 0 0 0;}
@font-face
	{font-family:LMRoman9-Italic;
	panose-1:0 0 0 0 0 0 0 0 0 0;}
 /* Style Definitions */
 p.MsoNormal, li.MsoNormal, div.MsoNormal
	{margin-top:0cm;
	margin-right:0cm;
	margin-bottom:6.0pt;
	margin-left:0cm;
	line-height:105%;
	font-size:11.0pt;
	font-family:"Calibri",sans-serif;}
p.MsoNoSpacing, li.MsoNoSpacing, div.MsoNoSpacing
	{margin:0cm;
	font-size:11.0pt;
	font-family:"Calibri",sans-serif;}
span.CodeZchn
	{mso-style-name:"Code Zchn";
	mso-style-link:Code;
	font-family:"Courier New";}
p.Code, li.Code, div.Code
	{mso-style-name:Code;
	mso-style-link:"Code Zchn";
	margin:0cm;
	font-size:9.0pt;
	font-family:"Courier New";}
.MsoChpDefault
	{font-size:10.0pt;
	font-family:"Calibri",sans-serif;}
@page WordSection1
	{size:595.3pt 841.9pt;
	margin:70.85pt 70.85pt 2.0cm 70.85pt;}
div.WordSection1
	{page:WordSection1;}
-->
</style>

</head>

<body lang=EN-GB style='word-wrap:break-word'>

<div class=WordSection1>

<p class=MsoNoSpacing><a name="_Hlk105598784">Document number:&nbsp; P2601R0 </a></p>

<p class=MsoNoSpacing>Date: 2022-06-11</p>

<p class=MsoNoSpacing style='margin-bottom:12.0pt'>Reply-to: Justin Cooke
&lt;jgc@cems.de&gt;<br>
Target audience: EWG, CWG</p>

<p class=MsoNormal style='margin-top:6.0pt'><b><span style='font-size:12.0pt;
line-height:105%'>&nbsp;</span></b></p>

<p class=MsoNormal style='margin-top:6.0pt'><b><span style='font-size:12.0pt;
line-height:105%'>Make redundant empty angle brackets optional</span></b></p>

<p class=MsoNormal style='margin-top:6.0pt'><b>&nbsp;</b></p>

<p class=MsoNormal style='margin-top:6.0pt'><b>Proposal:</b> To make redundant
empty angle brackets optional for class template argument lists.&nbsp; </p>

<p class=MsoNormal style='margin-top:6.0pt'><b>&nbsp;</b></p>

<p class=MsoNormal style='margin-top:6.0pt'><b>Motivation</b>.&nbsp; 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 <span class=CodeZchn><span style='font-size:9.0pt;
line-height:105%'>std::vector</span></span> took just one parameter, the value
type; the allocator parameter was added later, with a default argument.&nbsp;
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:</p>

<p class=Code>template &lt;typename T = int&gt; class C {};</p>

<p class=Code>C c;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
//<i><span style='font-family:"Times New Roman",serif'>OK&nbsp; (1)</span></i></p>

<p class=Code>extern C
x;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
//<i><span style='font-family:"Times New Roman",serif'>error: need</span></i>
C&lt;&gt;</p>

<p class=Code>C *p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
//<i><span style='font-family:"Times New Roman",serif'>error: need</span></i>
C&lt;&gt;</p>

<p class=Code>C
a[2];&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
//<i><span style='font-family:"Times New Roman",serif'>error: need</span></i>
C&lt;&gt;</p>

<p class=Code>C &amp;r =
c;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
//<i><span style='font-family:"Times New Roman",serif'>error: need</span></i>
C&lt;&gt;</p>

<p class=Code>struct S { C c; };&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //<i><span
style='font-family:"Times New Roman",serif'>error: need</span></i> C&lt;&gt;</p>

<p class=Code>struct D : C {};&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
//<i><span style='font-family:"Times New Roman",serif'> error: need</span></i>
C&lt;&gt;</p>

<p class=Code>std::vector&lt;C&gt; v;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //<i><span style='font-family:"Times New Roman",serif'>
error: need&nbsp; </span></i>C&lt;&gt;</p>

<p class=Code>void foo(C c);&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //<i><span
style='font-family:"Times New Roman",serif'> error: need</span></i> C&lt;&gt;</p>

<p class=MsoNormal style='margin-top:6.0pt'>The empty angle brackets are
currently optional only in case (1).&nbsp; 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 <i>Note 5</i>).&nbsp; This change
will allow class library maintainers to upgrade existing class definitions to
templates without breaking user code.</p>

<p class=MsoNormal style='margin-top:6.0pt'><b>&nbsp;</b></p>

<p class=MsoNormal style='margin-top:6.0pt'><b>Effect on existing code</b>:
None. Code using the proposed feature is ill-formed under C++20 and earlier
standards.</p>

<p class=MsoNormal style='margin-top:6.0pt'><b><i>Note:</i></b> 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 <i>parameter</i> lists, which are required to disambiguate explicit
full specialization declarations (13.9.4) from explicit instantiation
declarations (13.9.3).</p>

<p class=MsoNormal style='margin-top:6.0pt'><b>&nbsp;</b></p>

<p class=MsoNormal style='margin-top:6.0pt'><b>Wording: </b>(edits to N4910)</p>

<p class=MsoNoSpacing style='margin-top:6.0pt;margin-right:0cm;margin-bottom:
6.0pt;margin-left:35.4pt'><b><span style='font-family:"Times New Roman",serif'>13.4.1</span></b><span
style='font-family:"Times New Roman",serif'>&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span
style='font-size:10.0pt;font-family:"Times New Roman",serif'>&nbsp;<b>[temp.arg.general]</b></span></p>

<p class=MsoNoSpacing style='margin-top:6.0pt;margin-right:0cm;margin-bottom:
6.0pt;margin-left:35.4pt'>&#8230;</p>

<p class=MsoNormal style='margin-top:6.0pt;margin-right:0cm;margin-bottom:6.0pt;
margin-left:35.4pt;line-height:normal;text-autospace:none'><b><sup><span
style='font-family:"Times New Roman",serif'>5</span></sup></b><span
style='font-size:10.0pt;font-family:"Times New Roman",serif;color:black'> When
template argument packs or default </span><i><span style='font-size:10.0pt;
font-family:"Times New Roman",serif;color:#333333'>template-argument</span></i><span
style='font-size:10.0pt;font-family:"Times New Roman",serif;color:black'>s are
used, <u><span style='background:lime'>or template arguments are deduced
(13.10.3),</span></u> a </span><i><span style='font-size:10.0pt;font-family:
"Times New Roman",serif;color:#333333'>template-argument </span></i><span
style='font-size:10.0pt;font-family:"Times New Roman",serif;color:black'>list
can be empty. In that case the empty &lt;&gt; brackets <u><span
style='background:lime'>may be omitted</span></u> <s><span style='background:
red'>shall still</span> <span style='background:red'>be used as the </span></s></span><i><s><span
style='font-size:10.0pt;font-family:"Times New Roman",serif;color:#333333;
background:red'>template-argument-</span></s></i><i><s><span style='font-family:
"Times New Roman",serif;color:#333333;background:red'>list</span></s></i><i><s><span
style='font-family:"Times New Roman",serif;color:#333333'> </span></s></i><u><span
style='font-size:10.0pt;font-family:"Times New Roman",serif;color:black;
background:lime'>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</span></u><u><span style='font-size:9.0pt;font-family:"Times New Roman",serif;
color:black;background:lime'>)</span></u><span style='font-size:9.0pt;
font-family:"Times New Roman",serif;color:black'>.</span></p>

<p class=MsoNormal style='margin-top:6.0pt;margin-right:0cm;margin-bottom:6.0pt;
margin-left:35.4pt;line-height:normal;text-autospace:none'><span
style='font-size:9.0pt;font-family:LMRoman9-Regular;color:black'>[</span><i><span
style='font-size:9.0pt;font-family:LMRoman9-Italic;color:black'>Example 5 </span></i><span
style='font-size:9.0pt;font-family:LMRoman9-Regular;color:black'>:</span></p>

<p class=Code style='margin-left:35.4pt'>template&lt;class T = char&gt; class
String;</p>

<p class=Code style='margin-left:35.4pt'>String&lt;&gt;* p; <i><span
style='font-family:LMRoman9-Italic'>// OK, </span></i>String&lt;char&gt;</p>

<p class=Code style='margin-left:35.4pt'>String* q; <i><span style='font-family:
LMRoman9-Italic'>// <s><span style='color:black;background:red'>syntax error</span></s>
<u><span style='color:black;background:lime'>OK, empty brackets &lt;&gt;
omitted</span></u></span></i></p>

<p class=Code style='margin-left:35.4pt'>template&lt;class ... Elements&gt;
class Tuple;</p>

<p class=Code style='margin-left:35.4pt'>Tuple&lt;&gt;* t; <i><span
style='font-family:LMRoman9-Italic'>// OK, </span></i>Elements <i><span
style='font-family:LMRoman9-Italic'>is empty</span></i></p>

<p class=Code style='margin-left:35.4pt'>Tuple* u; <i><span style='font-family:
LMRoman9-Italic'>// <s><span style='color:black;background:red'>syntax error</span></s>
<u><span style='color:black;background:lime'>OK, empty brackets &lt;&gt;
omitted</span></u></span></i></p>

<p class=MsoNormal style='margin-top:6.0pt;margin-right:0cm;margin-bottom:6.0pt;
margin-left:35.4pt'><i><span style='font-size:9.0pt;line-height:105%;
font-family:LMRoman9-Italic;color:black'>&#8212;end example</span></i><span
style='font-size:9.0pt;line-height:105%;font-family:LMRoman9-Regular;
color:black'>]</span></p>

<p class=MsoNormal style='margin-top:6.0pt'><span style='color:black'>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.</span></p>

<p class=MsoNormal style='margin-top:6.0pt'><span style='color:black'>&nbsp;</span></p>

</div>

</body>

</html>
