Reputation: 10557
Look at the code:
template <class x> struct Foo
{
int getX(x *p) { return(0); }
enum E12 { a };
};
template <> int Foo<int>::getX(int*)
{
return(-15);
}
template <> enum Foo<int>::E12
{
a, b, c
}
As it was discussed in Cannot overload function, the first specialization is legal and even works in MSVC. While the second specialization for enum
does not even want to compile, saying "error C2988: unrecognizable template declaration/definition".
It seems to me that C++ is making relaitively unlogical exception for methods. Enum is just an example. The same thing can be applied to member classes, typedefs, etc.
I will be happy is some body will comment on this.
Upvotes: 1
Views: 556
Reputation: 137940
This is a very obscure new feature of C++11. File a bug report with Microsoft, although it is unlikely it will be given priority as almost nobody is aware this is allowed. The correct syntax would be
template <class x> struct Foo
{
int getX(x *p) { return(0); }
enum E12 { a };
};
template <> int Foo<int>::getX(int*)
{
return(-15);
}
template <> enum Foo<int>::E12
{
a, b, c
};
I've filed a bug with GCC. Can someone test on recent Clang?
In C++03, only classes and functions may be explicitly specialized. From the standard, C++03 14.7.3/1:
An explicit specialization of any of the following:
- function template
- class template
- member function of a class template
- static data member of a class template
- member class of a class template
- member class template of a class or class template
- member function template of a class or class template
can be declared by a declaration introduced by
template<>
A member enum is not such a case. (Generally speaking, an enum
type is always defined only once at its first declaration.)
To obtain a templated enum
or typedef
, you can wrap it in a class template. In your case, it would be a member class template of Foo
. Such a construct is called a metafunction.
C++11 also has alias templates, which are like templated typedefs, but they cannot be explicitly specialized.
The policy of only allowing classes and functions to be specialized, and then allowing such templates to encapsulate other things like enum
and typedef
, seems more consistent to me than allowing direct specialization of enum
. But, perhaps the language is going in your preferred direction.
Upvotes: 1