This question is connected to a previous Q&A in which a bug report for gcc was mentioned (supposedly fixed in gcc 4.5.0) and concerns some peculiarities for partial specialization of nested class template.
My setup is that I have a class Base
with a nested class template Inner
that is partially specialized for char
(using the dummy parameter trick, because explicit speciliaztion is not allowed in-class).
#include <type_traits>
#include <iostream>
#include <ios>
struct Base
{
// dummy template parameter...
template<class U, class _ = void> struct Inner: std::true_type {};
// ... to allow in-class partial specialization
template<class _> struct Inner<char, _>: std::false_type {};
};
I now define a Derived
class for which I further want to specialize Inner
, which for some odd reason cannot be done in-class (even though it is still a partial specialization).
struct Derived
:
Base
{
// cannot partially specialize Inner inside Derived...
//template<class _>
//struct Inner<int, _>: std::false_type {};
};
// ... but specializing Derived::Inner at namespace scope, also specializes it for Base::Inner
template<class _> struct Derived::Inner<int, _>: std::false_type {};
First question: why do I have to partially specialize Derived::Inner
at namespace scope?
But the strangest part is that when I call the various partial specializations of Inner
from both Base
and Derived
, the partial specialization for int
that I only did for Derived
, also applies to Base
.
int main()
{
std::cout << std::boolalpha << Base::Inner<float>::value << "\n";
std::cout << std::boolalpha << Derived::Inner<float>::value << "\n";
std::cout << std::boolalpha << Base::Inner<char>::value << "\n";
std::cout << std::boolalpha << Derived::Inner<char>::value << "\n";
std::cout << std::boolalpha << Base::Inner<int>::value << "\n"; // huh???
std::cout << std::boolalpha << Derived::Inner<int>::value << "\n"; // OK
}
Second question: why is Base::Inner<int>::value
equal to false
, even though only Derived::Inner<int>
was partially specialized?
Online example using gcc 4.8.0. I am specifically looking for quotes from the Standard that explain this behavior.