With C++11's strongly typed enum
s, it is possible to declare a member enumeration of a class like so:
class X {
public:
enum class E;
};
enum class X::E { a, b };
However, when making X
a class template:
template <typename T>
class X {
public:
enum class E;
};
template <typename T>
enum class X<T>::E { a, b };
gcc 4.7.2 and clang 3.0 both complain with "error: ‘enum X::E’ is an enumeration template [-pedantic]" and "error: enumeration cannot be a template", respectively. The section of the standard I think is relevant (and which, in fact, this question originated from) is §14 Templates, the first paragraph of which states:
The declaration in a template-declaration shall
- declare or define a function or a class, or
- define a member function, a member class, a member enumeration, or a static data member of a class template or of a class nested within a class template, or
- define a member template of a class or class template, or
- be an alias-declaration.
(emphasis mine). So is this a compiler bug, or am I mis-interpreting the statement entirely?
Forward-declaring class templates is as easy as a normal class declaration: template <typename T, typename U> class X; It is also possible to provide forward declarations for specializations of those class templates: template <typename U> class X<int, U>; template <> class X<int, int>;
It is also possible to provide forward declarations for specializations of those class templates: When we instantiate a class template that is parametrized with one of our types, the question arises whether it is sufficient to only have a forward declaration of our type.
It needs one if we use one of its members or the base class, or if it has to know how large objects of that class are. One should think that the same applies to enums, but that’s not the case. Forward-declaring plain old enums is not possible. The good news is, that we can provide forward declarations for scoped enums aka. enum classes.
Do not do this! It’s simply wrong. std::string is not a class, but a typedef to std::basic_string. And no, you can’t simply add a forward declaration to template class basic_string; because that’s not all there is to it, either.
I have been asked for creating this answer. See paragraph [temp.mem.enum] 14.5.1.4/1 of the C++ standard:
An enumeration member of a class template may be defined outside the class template definition. [ Example:
template<class T> struct A { enum E : T; }; A<int> a; template<class T> enum A<T>::E : T { e1, e2 }; A<int>::E e = A<int>::e1;
—end example ]
Newer version of clang (3.4) compiles your code successfully with flag -pedantic-errors
whereas gcc 4.8.1 still considers it is an error. I think it is a gcc bug.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With