Я просматривал раздел шаблонов C++ в часто задаваемых вопросах по C++ и наткнулся на этот пример (кода который не компилируется) относительно использования независимых вложенных классов родительского шаблона class как члены дочернего класса:
template<typename T>
class B {
public:
class Xyz { ... }; ← type nested in class B<T>
typedef int Pqr; ← type nested in class B<T>
};
template<typename T>
class D : public B<T> {
public:
void g()
{
Xyz x; ← bad (even though some compilers erroneously (temporarily?) accept it)
Pqr y; ← bad (even though some compilers erroneously (temporarily?) accept it)
}
};
Часто задаваемые вопросы по С++ 35.18
К сожалению, это тоже не работает, потому что эти имена (вы готовы? вы садитесь?) не обязательно являются типами. "Хм?!?" ты говоришь. "Не типы?!?" — восклицаешь ты. "Это сумасшествие, любой дурак может ВИДЕТЬ, что они типы; только взгляните!!!" вы протестуете. Извините, дело в том, что они могут быть не типами. Причина в том, что может быть специализация B, скажем, B, где B::Xyz является членом данных, например. Из-за этой потенциальной специализации компилятор не может предположить, что B::Xyz является типом, пока не узнает T. Решение состоит в том, чтобы дать компилятору подсказку с помощью ключевого слова typename:
Итак, автор утверждает, что there can be a specialization of B<T>, say B<Foo>, where B<Foo>::Xyz is a data member, for example.
. Это та часть, которую я действительно не понимаю - как можно было бы специализировать класс-шаблон (без наследования от него) добавить еще один член в класс, который в другой специализации (например, B<Baz>
) не существовал бы ? Это, конечно, при условии, что такие вещи, как D static if, не существуют.
Я что-то упускаю?