Does anyone know if this explicit specialization is or is not valid:
template <class>
struct L {
template <typename T>
struct O {
template <typename U>
static void Fun(U);
};
};
template<>
template<typename T>
template<typename U>
void L<int>::O<T>::Fun(U) {}
clang trunk (12/3/2013) gives the following error:
f:...\test.cpp:36:20: error: out-of-line definition of 'Fun' from class 'O' without definition
void L<int>::O<T>::Fun(U) {}
~~~~~~~~~~~~~~^
1 error generated.
Any supporting references from the standard to justify your answer will be greatly appreciated!
Note: I am somewhat surprised that it is an error - I would expect the specialization to be picked for any family of template arguments with which 'Fun' is instantiated beginning with <int><?any><?any>.
Is this a clang bug or a bug in my expectations?
Thank you!
====== EDIT (I think I have an answer) ========
OK - i think i found the supporting wording - from N3797 (post-chicago 2013 working draft) - 14.7.3/16 =>
"In an explicit specialization declaration for a member of a class template or a member template that appears in namespace scope, the member template and some of its enclosing class templates may remain unspecialized, except that the declaration shall not explicitly specialize a class member template if its enclosing class templates are not explicitly specialized as well."
If i interpret this correctly, we need an explicit specialization of O if we're going to declare an explicit specialization of its member? Hence the error.
Correct?
Thanks!
I don't believe it is valid. I'm not deep enough in the language to tell you how/if you can do this without providing the top-level specialization as done below, or if there is a shortcut for skipping the replicate templates, but the error message is fairly clear: You're trying to provide an implementation of a static member of a dependent nested type without providing the specialization of the actual dependency. I.e. this works:
Output