问题
Consider a code:
#include <iostream>
template <class T>
struct outer {
template <class... Args>
struct inner {
static constexpr bool value = false;
};
template <class... Other>
struct inner<T, Other...> {
static constexpr bool value = true;
};
};
int main() {
std::cout << outer<int>::inner<int, void>::value << std::endl;
};
It does compile in both g++ and clang++ but I am not convinced it is legal. As far as I know one cannot for example specialize template method for template class if not explicit specializing the class itself. How come rules are different for inner classes?
回答1:
A partial specialization of a nested template class is OK:
template <class T>
struct outer {
// template
template <class... Args>
struct inner {};
// partial
template <class... Other>
struct inner<T, Other...> {};
// error: explicit specialization in non-namespace scope ‘struct inner’
// template <>
// struct inner<char, int> {};
};
An explicit (full) specialization of the inner class only is not.
Explicit specializations of the outer class (without specialization of the inner class (which is actually a different class)) and explicit specializations of the outer and inner class are possible:
#include <iostream>
template <class T>
struct outer {
template <class... Args>
struct inner
{
static void print() { std::cout << "outer<T>::inner<Args...>\n"; }
};
};
template <> // outer specialization
struct outer<int>
{
template <class... Args>
struct inner
{
static void print() { std::cout << "outer<int>::inner<Args...>\n"; }
};
};
template <> // outer specialization
template <> // inner specialization
struct outer<int>::inner<int> // must be outside of the outer class
{
static void print() { std::cout << "outer<int>::inner<int>\n"; }
};
int main() {
outer<char>::inner<char>::print();
outer<int>::inner<char>::print();
outer<int>::inner<int>::print();
}
Note: The same applies to non variadic nested template classes.
来源:https://stackoverflow.com/questions/37766902/is-it-legit-to-specialize-variadic-template-class-inside-other-template-class