This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 119a. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.
2025-12-20
[Voted into WP at August, 2010 meeting.]
The Standard is currently silent on the dependency status ofenumerations and enumerators that are members of class templates.There are three questions that must be answered in this regard:
Are enumeration members of class templates dependenttypes?
It seems clear that nested enumerations must be dependent. Forexample:
void f(int); template<typename T> struct S { enum E { e0 }; void g() { f(e0); } }; void f(S<int>::E); void x() { S<int> si; si->g(); // Should call f(S<int>::E) }Issizeof applied to a nested enumeration avalue-dependent expression (13.8.3.4 [temp.dep.constexpr])?
There are three distinct cases that might have different answersto this question:
template<typename T> struct S { enum E { e0 }; };Here, the size ofE is, in principle, known at the timethe template is defined.
template<short I> struct S { enum E { e0 = I }; };In this case, the minimum size required forE cannot bedetermined until instantiation, but it is clear that the underlyingtype need be no larger thanshort.
template<typename T> struct S { enum E { e0 = T::e0; }; }Here, nothing can be known about the size ofE at the timethe template is defined.
13.8.3.4 [temp.dep.constexpr] paragraph 2 says that asizeof expression is value-dependent if the type of theoperand is type-dependent. Unless enumerations are given specialtreatment, all three of these examples will have value-dependentsizes. This could be surprising for the first case, at least, if notthe second as well.
Are nested enumerators value-dependent expressions?
Again the question of dependent initializers comes into play. As anexample, consider:
template<short I> struct S { enum E { e0, e1 = I, e2 }; };There seem to be three possible approaches as to whether theenumerators ofE are value-dependent:
The enumerators of a nested enumeration are allvalue-dependent, regardless of whether they have a value-dependentinitializer or not. This is the current position of 13.8.3.4 [temp.dep.constexpr] paragraph 2, which says that an identifier isvalue-dependent if it is a name declared with a dependenttype.
The enumerators of a nested enumeration are all value-dependentif any of the enumeration's enumerators has a value-dependentinitializer. In this approach,e0 would be value-dependent,even though it is clear that it has the value 0.
An enumerator of a nested enumeration is value-dependent onlyif it has a value-dependent initializer (explict or implicit). Thisapproach would makee1 ande2 value-dependent, butnote0.
An example that bears on the third approach is the following:
template<typename T> struct S { enum E { N = UINT_MAX, O = T::O }; int a[N + 2]; };With the normal treatment of enumerations, the type ofamight be eitherint[UINT_MAX+2] orint[1], dependingon whether the value ofT::O was such that the underlyingtype ofE isunsigned int orlong.
One possibility for addressing this problem under the thirdapproach would be to treat a given enumerator as having the type ofits initializer in such cases, rather than the enumeration type. Thiswould be similar to the way enumerators are treated within theenumerator list, before the enumeration declaration is complete(9.8.1 [dcl.enum] paragraph 5). The argument against thisis that it makes arithmetic using enumerators behave differently whenthe enumeration is a member of a class template and when it is not.
Notes from the April, 2005 meeting:
The CWG agreed on the following positions:
Nested enumerations are dependent types.
The result of thesizeof operator applied to anested enumeration is value-dependent unless there are nodependent initializers in its definition; the first case aboveis not dependent, while the second and third are dependent.
The approach described in 3.C above is correct. This issimilar to the treatment of static const integral data members,which are dependent only if their initializer is dependent.
Notes from the October, 2005 meeting:
There was no consensus among the CWG regarding question #3(which enumerators should be considered value-dependent). Theargument in favor of 3.C is principally that the values of enumeratorswith non-dependent initializers are known at definition time, so thereis no need to treat them as dependent.
One objection to 3.C is that, according to the consensus of theCWG, the enumeration type is dependent and thus even the known valuesof the enumeration would have a dependent type, which could affect theresults when such enumerations are used in expressions. A possibleresponse to this concern would be to treat non-dependent initializersas having the type of the initializer rather than the enumerationtype, similar to the treatment of enumerators withintheenumerator-list (9.8.1 [dcl.enum] paragraph 5).However, this approach would be inconsistent with the treatment ofother enumeration types. It would also interfere with overloadresolution (e.g., the call in the example under question #1 abovewould resolve tof(int) with this approach ratherthanf(S<int>::E)).
Those in favor of option 3.A also suggested that it would be simplerand require less drafting: if all the enumerators have the (dependent)type of the enumeration, 13.8.3.4 [temp.dep.constexpr] paragraph 2already says that a name with a dependent type is value-dependent, sonothing further would need to be said. Option 3.C would requireadditional caveats to exempt some enumerators.
The proponents of 3.A also pointed out that there are many othercases where a known value with a dependent type is treated as dependent:
static const T t = 0; ... A<t> ...
or
template <int I> void f() { g(I-I); }With regard to current practice, g++ and MSVC++ implement 3.A, whileEDG implements 3.C.
Notes from the July, 2009 meeting:
The consensus of the CWG was that all the types and values aredependent.
Proposed resolution (June, 2010):
Change 13.8.3.2 [temp.dep.type] paragraph 6 asfollows:
A type is dependent if it is
...
a nested classor enumeration that is a memberof the current instantiation,
...