Я просматривал раздел шаблонов C ++ на C ++ FAQ и наткнулся на этот пример (кода, который не компилируется) относительно используя независимые вложенные классы родительского шаблонного класса в качестве членов дочернего класса:
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)
}
};
К сожалению, это не работает, потому что эти имена (вы
готовы? ты сидишь?) не обязательно типа. «А?!?» вы
сказать. «Не типы?!?» Вы восклицаете. «Это безумие; любой дурак может ВИДЕТЬ, что они
типы; просто посмотрите !!! «Вы протестуете. Извините, дело в том, что они
не может быть типов. Причина в том, что может быть специализация
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 статичен, если не существует
Я что-то пропустил?
Когда вы явно специализируете шаблон класса, вы полностью переопределяете класс для заданных аргументов шаблона. Вот простой пример:
template <typename T>
struct foo
{
typedef T type;
};
template <>
struct foo<int>
{
static int type;
};
Теперь, если я создаю экземпляр foo
с любым другим аргументом шаблона, чем int
член type
это тип. В противном случае это int
элемент данных.
Других решений пока нет …