Re: referring to enum values in a template
Re: referring to enum values in a template
- Subject: Re: referring to enum values in a template
- From: James Widman <email@hidden>
- Date: Sun, 29 Jan 2006 01:19:47 -0500
Hi Nathan,
On Jan 27, 2006, at 9:11 PM, Nathan Roberts wrote:
Hello all,
I'm converting a CodeWarrior project to XCode, and I'm down to two
lines that won't compile. The lines are template code, and they
fail during instantiation. In fact, the two lines look pretty much
equivalent, so I'll just include code for one.
Basically, I've got an enum that's defined in a template class.
Minor nit: we say "class template" when referring to the template (as
opposed to instantiations of it). "Template class" is known these
days as a somewhat deprecated shorthand for "template
specialization". It sure does roll off the tongue more easily
though. (:
I'm trying to refer to one of the values of the enum. In CW this
compiled just fine when I had just the name of the enum value
(eNotice); gcc wants me to be more specific (I used
TVectorMessage<T>::ECode::eNotice). This latter seems to pass the
syntax check, and to give an error during instantiation (T =
STask), saying that 'eNotice' is not a member of
'TVectorMessage<STask>::ECode'.
I don't know if code will be necessary or helpful -- this may just
be a syntax thing
It is. Actually, there are two issues here, and both of them seem to
catch a lot of people off guard.
I've boiled your example down a little so that we can (a) try to
compile it and (b) discuss it within a reasonable period of time. (:
template <class T> struct A
{
enum E { e0, e1, e2, e3 };
A( E, E ){}
};
template <class T> struct B : public A<T>
{
B() : A<T>(
// what you had in your example:
A<T>::E::e3,
// what you probably had before GCC complained:
e3 )
{}
};
B<int> bi; // elicit instantiation
Messages from GCC 4.0.1 are:
t.cpp: In constructor 'B<T>::B()':
t.cpp:14: error: 'e3' was not declared in this scope
t.cpp: In constructor 'B<T>::B() [with T = int]':
t.cpp:18: instantiated from here
t.cpp:14: error: 'e3' is not a member of 'A<int>::E'
[Note that there is no 'with' clause for the error about e3: that
message was issued during the definition of the template -- not its
instantiation.]
Issue 1: Base classes of dependent type (or, during instantiation,
of formerly-dependent type) are not searched during unqualified name
lookup. (14.6.2p3) Why do we need this rule? Suppose we allowed
unqualified lookup to look-up in ex-dependent base classes at
instantiation time; and suppose we had the code:
template <class T> struct A
{
enum E { e0, e1, e2, e3 };
A(E) {}
};
const int e3 = 4;
template <class T> struct B : public A<T>
{
B() : A<T>( e3 ) {} // which e3?
};
B<int> bi;
Now, during the definition of the primary template B, we can't look
in A<T> -- it might later be explicitly or partially specialized, and
so we can't assume that all future instantiations of A will contain
'enum E'. So we find the 'e3' in the global namespace.
Later, we instantiate. At that time, it's possible to look in the
base class because it's no longer dependent: we know for certain what
its members are. Now, we actually won't go looking for e3 in this
case, because we already did the lookup at template definition time
(14.6.3). But if we *were* to do lookup anyway, we would find a
completely different symbol: ::A<int>::e3. The "would-be" name
lookup has to be consistient. Why? It has something to do with
'export', and that's all I'm going to say about that. (:
Issue 2: Enums do not introduce a new scope; instead, enumeration
constants ([e0-e3] above) are injected into the scope where the
enumeration type name resides. So instead, you should use:
B() : A<T>( A<T>::e3, A<T>::e3 )
Again, GCC won't look in A<T> at template def time; instead it will
just record the fact that a dependent expression was seen. During
instantiation time, it will finally be able to look in a concrete
scope -- A<int> -- and it will find ::A<int>::e3.
HTH,
James
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Xcode-users mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden