Рассмотрите следующее:
template <typename T>
class Base {
public:
template <typename U>
class Nested { };
};
template <typename T>
class Derived : public Base<T> {
public:
//How do we typedef of redefine Base<T>::Nested?
using Base<T>::Nested; //This does not work
using Base<T>::template<typename U> Nested; //Cannot do this either
typedef typename Base<T>::template<typename U> Nested Nested; //Nope..
//now we want to use the Nested class here
template <typename U>
Class NestedDerived : public Nested { };
//or like this:
Nested<int> nestedVar; // obviously does not work
};
Как использовать шаблонный Вложенный класс в Производном классе? Действительно ли это возможно сделать в текущей версии стандарта C++?
На самом деле использование
работает так, как рекламируется, просто оно не избавляет от проблемы зависимого имени в шаблоне и в настоящее время не может напрямую псевдонизировать шаблоны (будет исправлено в C++0x):
template <class T>
struct Base {
template <class U> struct Nested {};
};
template <class T>
struct Derived : Base<T> {
using Base<T>::Nested;
// need to prefix Nested with template because
// it is a dependent template:
struct X : Base<T>::template Nested<int> {};
// same here:
template<class U>
struct Y : Base<T>::template Nested<U> {};
// data member, typename is needed here:
typename Base<T>::template Nested<int> data;
};
void f() {
Derived<int>::Nested<int> n; // works fine outside
}
Есть еще одна возможная загвоздка при использовании Derived
в шаблонах, но это опять же проблема зависимого имени, а не наследования:
template<class T>
void g() {
// Nested is a dependent type and a dependent template, thus
// we need 'typename' and 'template':
typedef typename Derived<T>::template Nested<int> NestedInt;
}
Просто помните, что имена, зависящие от аргументов шаблона, должны иметь
typename
, если это зависимый тип: typename A::B
template
, если это зависимый шаблон: A::template f()
typename A::template B
typename
является незаконным в списках базовых классов: template struct A : B, C::template D {};
Я все еще не уверен на 100%, что вы хотите, но вы можете попробовать.
Это скомпилировано в Visual Studio
template <typename T>
class Base {
public:
template <typename U>
class Nested { };
};
template <typename T>
class Derived : public Base<T> {
public:
//now we want to use the Nested class here
template <typename U>
class NestedDerived : public Nested<U> { };
};
int _tmain(int argc, _TCHAR* argv[])
{
Base<int>::Nested<double> blah2;
Derived<int>::NestedDerived<int> blah;
return 0;
}
Кажется, это работает:
(EDIT: добавил еще несколько строк, чтобы показать первый шаблонный оператор. И спасибо Самиру Талвару за исправление моего форматирования! )
template <typename T, typename U>
class Derived : public Base<T> {
public:
typedef typename Base<T>::template Nested<U> Nested;
class NestedDerived : public Nested { };
Nested nestedVar;
};
Попробуйте следующее:
template <typename T>
class Base {
public:
template <typename U>
class Nested { };
};
template <typename T>
class Derived : public Base<T> {
public:
//How do we typedef of redefine Base<T>::Nested?
//using Base<T>::Nested; //This does not work
//using Base<T>::template<typename U> Nested; //Cannot do this either
//typedef typename Base<T>::template<typename U> Nested Nested; //Nope..
//now we want to use the Nested class here
template <typename U>
class NestedDerived : public Base<T>::template Nested<U> { };
};
int main()
{
Base<int>::Nested<double> nested;
Derived<int>::NestedDerived<double> nested_derived;
return 0;
}
Скомпилировано нормально с использованием gcc 4.3.3 на Slackware 13