Этот вопрос связан с a previous Q&A, в котором упоминается отчет об ошибке для gcc (предположительно фиксированный в gcc 4.5.0) и касается некоторых особенностей частичной специализации шаблона вложенного класса.Понятие частичной специализации унаследованных вложенных шаблонов классов
Моей установкой является то, что у меня есть класс Base
с шаблоном вложенного класса Inner
, который частично специализирован для char
(с использованием фиктивного параметра трюка, так как явное speciliaztion не допускаются в классе).
#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 {};
};
я теперь определить Derived
класс, для которого я также хочу специализироваться Inner
, который по какой-то причине не может быть сделано в классе (даже если он по-прежнему частичная специализация).
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 {};
Первый вопрос: почему я должен частично специализировать Derived::Inner
в области видимости пространства имен?
Но самое странное в том, что, когда я называю различные частичные специализации Inner
как из Base
и Derived
, частичной специализации int
, что я сделал только для Derived
, также относится и к 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
}
Второй вопрос: почему Base::Inner<int>::value
равно false
, хотя только Derived::Inner<int>
был частично специализированный?
Online example using gcc 4.8.0. Я специально ищу цитаты из Стандарта, которые объясняют это поведение.
tnx для ответа + стандартная цитата! – TemplateRex
мое удовольствие! Я все еще не уверен, разрешаю ли объявление «Derived :: Inner» вне класса легально или ошибка компилятора. – willj