<!DOCTYPE html><html lang='en'><head><title>[temp.class.spec.match]</title><meta charset='UTF-8'/><link rel='stylesheet' type='text/css' href='14882.css'/><link rel='stylesheet' type='text/css' href='expanded.css' title='Notes and examples expanded'/><link rel='alternate stylesheet' type='text/css' href='colored.css' title='Notes and examples colored'/><link rel='alternate stylesheet' type='text/css' href='collapsed.css' title='Notes and examples collapsed'/><link rel='icon' href='icon.png'/></head><body><div class='wrapper'><h1 ><a class='secnum' style='min-width:73pt'>12</a> Templates <a class='abbr_ref' href='./#temp'>[temp]</a></h1><h2 ><a class='secnum' style='min-width:88pt'>12.6</a> Template declarations <a class='abbr_ref' href='temp.decls#temp.class.spec.match'>[temp.decls]</a></h2><h3 ><a class='secnum' style='min-width:103pt'>12.6.5</a> Class template partial specializations <a class='abbr_ref' href='temp.class.spec#match'>[temp.class.spec]</a></h3><h4 ><a class='secnum' style='min-width:118pt'>12.6.5.1</a> Matching of class template partial specializations <a class='abbr_ref'>[temp.class.spec.match]</a></h4><div class='para' id='1'><div class='marginalizedparent'><a class='marginalized' href='#1'>1</a></div><div class='sourceLinkParent'><a class='sourceLink' href='https://github.com/Eelis/draft73ca144c7e48612fe72742f9f6a5ec9ad6a934d2/source/templates.tex#L3155'>#</a></div><div id='1.sentence-1' class='sentence'>When a class template is used in a context that requires an instantiation of
the class,
it is necessary to determine whether the instantiation is to be generated
using the primary template or one of the partial specializations<a class='hidden_link' href='#1.sentence-1'>.</a></div> <div id='1.sentence-2' class='sentence'>This is done by matching the template arguments of the class template
specialization with the template argument lists of the partial
specializations<a class='hidden_link' href='#1.sentence-2'>.</a></div><div id='1.sentence-3' class='sentence'><ul class='itemize'><li id='1.1'><div class='marginalizedparent' style='left:-7em'><a class='marginalized' href='#1.1'>(1.1)</a></div><div id='1.1.sentence-1' class='sentence'>If exactly one matching specialization is found, the instantiation is
generated from that specialization<a class='hidden_link' href='#1.1.sentence-1'>.</a></div></li><li id='1.2'><div class='marginalizedparent' style='left:-7em'><a class='marginalized' href='#1.2'>(1.2)</a></div><div id='1.2.sentence-1' class='sentence'>If more than one matching specialization is found,
the <a href='temp.class.order'>partial order rules</a> are used to determine
whether one of the specializations is more specialized than the
others<a class='hidden_link' href='#1.2.sentence-1'>.</a></div> <div id='1.2.sentence-2' class='sentence'>If none of the specializations is more specialized than all of the
other matching specializations, then the use of the class template
is ambiguous and the program is ill-formed<a class='hidden_link' href='#1.2.sentence-2'>.</a></div></li><li id='1.3'><div class='marginalizedparent' style='left:-7em'><a class='marginalized' href='#1.3'>(1.3)</a></div><div id='1.3.sentence-1' class='sentence'>If no matches are found, the instantiation is generated from the
primary template<a class='hidden_link' href='#1.3.sentence-1'>.</a></div></li></ul></div></div><div class='para' id='2'><div class='marginalizedparent'><a class='marginalized' href='#2'>2</a></div><div class='sourceLinkParent'><a class='sourceLink' href='https://github.com/Eelis/draft73ca144c7e48612fe72742f9f6a5ec9ad6a934d2/source/templates.tex#L3181'>#</a></div><div id='2.sentence-1' class='sentence'>A partial specialization matches a given actual template argument
list if the template arguments of the partial specialization can be
<a href='temp.deduct'>deduced</a> from the actual template argument list,
and the deduced template arguments satisfy the <a href='temp.constr.decl#def:associated_constraints'>associated constraints</a>
of the partial specialization, if any<a class='hidden_link' href='#2.sentence-1'>.</a></div> <div id='2.example-1' class='example'>[<span style='white-space:nowrap'> </span><a class='example_link' href='#2.example-1'><span class='textit'>Example</span></a><div class='exampleBody'><span class='textit'>:</span> <pre class='codeblock'>
<span class='keyword'>template</span><span class='anglebracket'>&lt;</span><span class='keyword'>class</span> T1, <span class='keyword'>class</span> T2, <span class='keyword'>int</span> I<span class='anglebracket'>&gt;</span> <span class='keyword'>class</span> A             <span class='curlybracket'>{</span> <span class='curlybracket'>}</span>;    <span class='comment'>// #1</span>
<span class='keyword'>template</span><span class='anglebracket'>&lt;</span><span class='keyword'>class</span> T, <span class='keyword'>int</span> I<span class='anglebracket'>&gt;</span>            <span class='keyword'>class</span> A<span class='anglebracket'>&lt;</span>T, T<span class='operator'>*</span>, I<span class='anglebracket'>&gt;</span>   <span class='curlybracket'>{</span> <span class='curlybracket'>}</span>;    <span class='comment'>// #2</span>
<span class='keyword'>template</span><span class='anglebracket'>&lt;</span><span class='keyword'>class</span> T1, <span class='keyword'>class</span> T2, <span class='keyword'>int</span> I<span class='anglebracket'>&gt;</span> <span class='keyword'>class</span> A<span class='anglebracket'>&lt;</span>T1<span class='operator'>*</span>, T2, I<span class='anglebracket'>&gt;</span> <span class='curlybracket'>{</span> <span class='curlybracket'>}</span>;    <span class='comment'>// #3</span>
<span class='keyword'>template</span><span class='anglebracket'>&lt;</span><span class='keyword'>class</span> T<span class='anglebracket'>&gt;</span>                   <span class='keyword'>class</span> A<span class='anglebracket'>&lt;</span><span class='keyword'>int</span>, T<span class='operator'>*</span>, <span class='literal'>5</span><span class='anglebracket'>&gt;</span> <span class='curlybracket'>{</span> <span class='curlybracket'>}</span>;    <span class='comment'>// #4</span>
<span class='keyword'>template</span><span class='anglebracket'>&lt;</span><span class='keyword'>class</span> T1, <span class='keyword'>class</span> T2, <span class='keyword'>int</span> I<span class='anglebracket'>&gt;</span> <span class='keyword'>class</span> A<span class='anglebracket'>&lt;</span>T1, T2<span class='operator'>*</span>, I<span class='anglebracket'>&gt;</span> <span class='curlybracket'>{</span> <span class='curlybracket'>}</span>;    <span class='comment'>// #5</span>

A<span class='anglebracket'>&lt;</span><span class='keyword'>int</span>, <span class='keyword'>int</span>, <span class='literal'>1</span><span class='anglebracket'>&gt;</span>   a1;                    <span class='comment'>// uses #1</span>
A<span class='anglebracket'>&lt;</span><span class='keyword'>int</span>, <span class='keyword'>int</span><span class='operator'>*</span>, <span class='literal'>1</span><span class='anglebracket'>&gt;</span>  a2;                    <span class='comment'>// uses #2, <span class='tcode_in_codeblock'>T</span> is <span class='tcode_in_codeblock'>int</span>, <span class='tcode_in_codeblock'>I</span> is <span class='tcode_in_codeblock'>1</span></span>
A<span class='anglebracket'>&lt;</span><span class='keyword'>int</span>, <span class='keyword'>char</span><span class='operator'>*</span>, <span class='literal'>5</span><span class='anglebracket'>&gt;</span> a3;                    <span class='comment'>// uses #4, <span class='tcode_in_codeblock'>T</span> is <span class='tcode_in_codeblock'>char</span></span>
A<span class='anglebracket'>&lt;</span><span class='keyword'>int</span>, <span class='keyword'>char</span><span class='operator'>*</span>, <span class='literal'>1</span><span class='anglebracket'>&gt;</span> a4;                    <span class='comment'>// uses #5, <span class='tcode_in_codeblock'>T1</span> is <span class='tcode_in_codeblock'>int</span>, <span class='tcode_in_codeblock'>T2</span> is <span class='tcode_in_codeblock'>char</span>, <span class='tcode_in_codeblock'>I</span> is <span class='tcode_in_codeblock'>1</span></span>
A<span class='anglebracket'>&lt;</span><span class='keyword'>int</span><span class='operator'>*</span>, <span class='keyword'>int</span><span class='operator'>*</span>, <span class='literal'>2</span><span class='anglebracket'>&gt;</span> a5;                    <span class='comment'>// ambiguous: matches #3 and #5</span>
</pre> —<span style='white-space:nowrap'> </span><i>end example</i></div><span style='white-space:nowrap'> </span>]</div>  <div id='2.example-2' class='example'>[<span style='white-space:nowrap'> </span><a class='example_link' href='#2.example-2'><span class='textit'>Example</span></a><div class='exampleBody'><span class='textit'>:</span> <pre class='codeblock'>
<span class='keyword'>template</span><span class='anglebracket'>&lt;</span><span class='keyword'>typename</span> T<span class='anglebracket'>&gt;</span> <span class='keyword'>concept</span> C <span class='operator'>=</span> <span class='keyword'>requires</span> <span class='parenthesis'>(</span>T t<span class='parenthesis'>)</span> <span class='curlybracket'>{</span> t<span class='operator'>.</span>f<span class='parenthesis'>(</span><span class='parenthesis'>)</span>; <span class='curlybracket'>}</span>;

<span class='keyword'>template</span><span class='anglebracket'>&lt;</span><span class='keyword'>typename</span> T<span class='anglebracket'>&gt;</span> <span class='keyword'>struct</span> S <span class='curlybracket'>{</span> <span class='curlybracket'>}</span>;      <span class='comment'>// #1</span>
<span class='keyword'>template</span><span class='anglebracket'>&lt;</span>C T<span class='anglebracket'>&gt;</span> <span class='keyword'>struct</span> S<span class='anglebracket'>&lt;</span>T<span class='anglebracket'>&gt;</span> <span class='curlybracket'>{</span> <span class='curlybracket'>}</span>;          <span class='comment'>// #2</span>

<span class='keyword'>struct</span> Arg <span class='curlybracket'>{</span> <span class='keyword'>void</span> f<span class='parenthesis'>(</span><span class='parenthesis'>)</span>; <span class='curlybracket'>}</span>;

S<span class='anglebracket'>&lt;</span><span class='keyword'>int</span><span class='anglebracket'>&gt;</span> s1;                              <span class='comment'>// uses #1; the constraints of #2 are not satisfied</span>
S<span class='anglebracket'>&lt;</span>Arg<span class='anglebracket'>&gt;</span> s2;                              <span class='comment'>// uses #2; both constraints are satisfied but #2 is more specialized</span>
</pre> —<span style='white-space:nowrap'> </span><i>end example</i></div><span style='white-space:nowrap'> </span>]</div> </div><div class='para' id='3'><div class='marginalizedparent'><a class='marginalized' href='#3'>3</a></div><div class='sourceLinkParent'><a class='sourceLink' href='https://github.com/Eelis/draft73ca144c7e48612fe72742f9f6a5ec9ad6a934d2/source/templates.tex#L3216'>#</a></div><div id='3.sentence-1' class='sentence'>If the template arguments of a partial specialization cannot be deduced
because of the structure of its <i ><a href='temp#nt:template-parameter-list'>template-parameter-list</a></i>
and the <i ><a href='temp.names#nt:template-id'>template-id</a></i>,
the program is ill-formed<a class='hidden_link' href='#3.sentence-1'>.</a></div> <div id='3.example-1' class='example'>[<span style='white-space:nowrap'> </span><a class='example_link' href='#3.example-1'><span class='textit'>Example</span></a><div class='exampleBody'><span class='textit'>:</span> <pre class='codeblock'>
<span class='keyword'>template</span> <span class='anglebracket'>&lt;</span><span class='keyword'>int</span> I, <span class='keyword'>int</span> J<span class='anglebracket'>&gt;</span> <span class='keyword'>struct</span> A <span class='curlybracket'>{</span><span class='curlybracket'>}</span>;
<span class='keyword'>template</span> <span class='anglebracket'>&lt;</span><span class='keyword'>int</span> I<span class='anglebracket'>&gt;</span> <span class='keyword'>struct</span> A<span class='anglebracket'>&lt;</span>I<span class='operator'>+</span><span class='literal'>5</span>, I<span class='operator'>*</span><span class='literal'>2</span><span class='anglebracket'>&gt;</span> <span class='curlybracket'>{</span><span class='curlybracket'>}</span>;     <span class='comment'>// error</span>

<span class='keyword'>template</span> <span class='anglebracket'>&lt;</span><span class='keyword'>int</span> I<span class='anglebracket'>&gt;</span> <span class='keyword'>struct</span> A<span class='anglebracket'>&lt;</span>I, I<span class='anglebracket'>&gt;</span> <span class='curlybracket'>{</span><span class='curlybracket'>}</span>;         <span class='comment'>// OK</span>

<span class='keyword'>template</span> <span class='anglebracket'>&lt;</span><span class='keyword'>int</span> I, <span class='keyword'>int</span> J, <span class='keyword'>int</span> K<span class='anglebracket'>&gt;</span> <span class='keyword'>struct</span> B <span class='curlybracket'>{</span><span class='curlybracket'>}</span>;
<span class='keyword'>template</span> <span class='anglebracket'>&lt;</span><span class='keyword'>int</span> I<span class='anglebracket'>&gt;</span> <span class='keyword'>struct</span> B<span class='anglebracket'>&lt;</span>I, I<span class='operator'>*</span><span class='literal'>2</span>, <span class='literal'>2</span><span class='anglebracket'>&gt;</span> <span class='curlybracket'>{</span><span class='curlybracket'>}</span>;    <span class='comment'>// OK</span>
</pre> —<span style='white-space:nowrap'> </span><i>end example</i></div><span style='white-space:nowrap'> </span>]</div> </div><div class='para' id='4'><div class='marginalizedparent'><a class='marginalized' href='#4'>4</a></div><div class='sourceLinkParent'><a class='sourceLink' href='https://github.com/Eelis/draft73ca144c7e48612fe72742f9f6a5ec9ad6a934d2/source/templates.tex#L3233'>#</a></div><div id='4.sentence-1' class='sentence'>In a type name that refers to a class template specialization, (e.g.,
<span class='texttt'>A<span class='anglebracket'>&lt;</span><span class='keyword'>int</span>, <span class='keyword'>int</span>, <span class='literal'>1</span><span class='anglebracket'>&gt;</span></span>)
the argument list shall match the template parameter list of the primary
template<a class='hidden_link' href='#4.sentence-1'>.</a></div> <div id='4.sentence-2' class='sentence'>The template arguments of a specialization are deduced from the arguments
of the primary template<a class='hidden_link' href='#4.sentence-2'>.</a></div></div></div></body></html>