<HTML>
<HEAD>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<TITLE>
    CWG Issue 1206</TITLE>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<STYLE TYPE="text/css">
  INS { text-decoration:none; font-weight:bold; background-color:#A0FFA0 }
  .INS { text-decoration:none; background-color:#D0FFD0 }
  DEL { text-decoration:line-through; background-color:#FFA0A0 }
  .DEL { text-decoration:line-through; background-color: #FFD0D0 }
  @media (prefers-color-scheme: dark) {
    HTML { background-color:#202020; color:#f0f0f0; }
    A { color:#5bc0ff; }
    A:visited { color:#c6a8ff; }
    A:hover, a:focus { color:#afd7ff; }
    INS { background-color:#033a16; color:#aff5b4; }
    .INS { background-color: #033a16; }
    DEL { background-color:#67060c; color:#ffdcd7; }
    .DEL { background-color:#67060c; }
  }
  SPAN.cmnt { font-family:Times; font-style:italic }
</STYLE>
</HEAD>
<BODY>
<P><EM>This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21
  Core Issues List revision 118b.
  See http://www.open-std.org/jtc1/sc22/wg21/ for the official
  list.</EM></P>
<P>2025-09-28</P>
<HR>
<A NAME="1206"></A><H4>1206.
  
Defining opaque enumeration members of class templates
</H4>
<B>Section: </B>13.7.2&#160; [<A href="https://wg21.link/temp.class">temp.class</A>]
 &#160;&#160;&#160;

 <B>Status: </B>C++11
 &#160;&#160;&#160;

 <B>Submitter: </B>Jason Merrill
 &#160;&#160;&#160;

 <B>Date: </B>2010-10-06<BR>


<P>[Voted into the WP at the March, 2011 meeting as part of paper N3262.]</P>



<P>Presumably an out-of-class definition for an opaque enumeration
member of a class template is intended to be allowed; however, the
current wording of 13.7.2 [<A href="https://wg21.link/temp.class">temp.class</A>] provides only for
out-of-class definitions of member functions, member classes,
static data members, and member templates, not for opaque
enumerations.</P>

<P><B>Proposed resolution (November, 2010) [SUPERSEDED]:</B></P>

<OL>
<LI><P>Change Clause 13 [<A href="https://wg21.link/temp#1">temp</A>] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

<P>...The <I>declaration</I> in a <I>template-declaration</I> shall</P>

<UL>
<LI><P>declare or define a function or class, or</P></LI>

<LI><P>define a member function, a member class<INS>, a member
enumeration,</INS> or a static data member of a class template or of a
class nested within a class template, or</P></LI>

<LI><P>...</P></LI>

</UL>

</BLOCKQUOTE>

<LI><P>Change 13.7.2 [<A href="https://wg21.link/temp.class#3">temp.class</A>] paragraph 3 as follows:</P></LI>

<BLOCKQUOTE>

When a member function, a member class, <INS>a member
enumeration,</INS> a static data member or a member template of a
class template is defined outside of the class template definition...

</BLOCKQUOTE>

<LI><P>Add a new section following 13.7.2.5 [<A href="https://wg21.link/temp.static">temp.static</A>]:</P></LI>

<BLOCKQUOTE>

<P><B><INS>14.5.1.4 Enumeration members of class templates
[temp.mem.enum]</INS></B></P>

<P><INS>An enumeration member of a class template may be defined outside
the class template definition. [<I>Example:</I></INS></P>

<PRE>
<INS>  template&lt;class T&gt; struct A {
    enum E: T;
  };
  A&lt;int&gt; a;
  template&lt;class T&gt; enum A&lt;T&gt;::E: T { e1, e2 };
  A&lt;int&gt;::E e = A&lt;int&gt;::e1;</INS>
</PRE>

<P><INS>&#8212;<I>end example</I>]</INS></P>

</BLOCKQUOTE>

<LI><P>Change 13.9 [<A href="https://wg21.link/temp.spec#2">temp.spec</A>] paragraph 2 as follows:</P></LI>

<BLOCKQUOTE>

A function instantiated from a function template is called an
instantiated function. A class instantiated from a class template is
called an instantiated class. A member function, a member class,
<INS>a member enumeration,</INS> or a static data member of a class
template instantiated from the member definition of the class template
is called, respectively, an instantiated member function, member
class<INS>, member enumeration,</INS> or static data member.  A member
function...

</BLOCKQUOTE>

<LI><P>Change 13.9.2 [<A href="https://wg21.link/temp.inst#1">temp.inst</A>] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

...The implicit instantiation of a class template specialization
causes the implicit instantiation of the declarations, but not of the
definitions or default arguments, of the class member functions,
member classes, <INS>scoped member enumerations,</INS> static data
members and member templates; and it causes the implicit instantiation
of the definitions of <INS>unscoped member enumerations and</INS> member
anonymous unions. Unless a member...

</BLOCKQUOTE>

<LI><P>Change 13.9.4 [<A href="https://wg21.link/temp.expl.spec#1">temp.expl.spec</A>] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

<P>An explicit specialization of any of the following:</P>

<UL>
<LI><P>function template</P></LI>

<LI><P>class template</P></LI>

<LI><P>member function of a class template</P></LI>

<LI><P>static data member of a class template</P></LI>

<LI><P>member class of a class template</P></LI>

<LI><P><INS>member enumeration of a class template</INS></P></LI>

<LI><P>member class template of a class or class template</P></LI>

<LI><P>member function template of a class or class template</P></LI>

<P>can be declared by a declaration introduced by
<TT>template&lt;&gt;</TT>...</P>

</UL>

</BLOCKQUOTE>

<LI><P>Change 13.9.4 [<A href="https://wg21.link/temp.expl.spec#4">temp.expl.spec</A>] paragraph 4 as follows:</P></LI>

<BLOCKQUOTE>

A member function, a member class<INS>, a member enumeration,</INS> or
a static data member of a class template may be explicitly specialized
for a class specialization that is implicitly instantiated...

</BLOCKQUOTE>

<LI><P>Add the indicated text to the example in 13.9 [<A href="https://wg21.link/temp.spec#6">temp.spec</A>] paragraph 6:
</P></LI>

<PRE>
  template&lt;&gt; void sort&lt;&gt;(Array(&lt;char*&gt;&amp; v);        //<SPAN CLASS="cmnt"> OK: </SPAN>sort&lt;char*&gt;<SPAN CLASS="cmnt"> not yet used</SPAN>
<INS>  template&lt;class T&gt; struct A {
    enum E: T;
    enum class S: T;
  };
  template&lt;&gt; enum A&lt;int&gt;::E: int { eint };         //<SPAN CLASS="cmnt"> OK</SPAN>
  template&lt;&gt; enum class A&lt;int&gt;::S: int { sint };   //<SPAN CLASS="cmnt"> OK</SPAN>
  template&lt;class T&gt; enum A&lt;T&gt;::E: T { eT };
  template&lt;class T&gt; enum class A&lt;T&gt;::S: T { sT };
  template&lt;&gt; enum A&lt;char&gt;::E: int { echar };       //<SPAN CLASS="cmnt"> ill-formed, </SPAN>A&lt;char&gt;::E<SPAN CLASS="cmnt"> was instantiated when </SPAN>A&lt;char&gt;<SPAN CLASS="cmnt"> was instantiated</SPAN>
  template&lt;&gt; enum class A&lt;char&gt;::S: int { schar }; //<SPAN CLASS="cmnt"> OK</SPAN></INS>
</PRE>

<LI><P>Change 13.9.4 [<A href="https://wg21.link/temp.expl.spec#7">temp.expl.spec</A>] paragraph 7 as follows:</P></LI>

<BLOCKQUOTE>

The placement of explicit specialization declarations for function
templates, class templates, member functions of class templates,
static data members of class templates, member classes of class
templates, <INS>member enumerations of class templates,</INS> member
class templates of class templates, member function templates...

</BLOCKQUOTE>

</OL>

<BR><BR>
</BODY>
</HTML>
