На самом деле using
работает так, как объявлено, просто не избавляется от проблемы с зависимым именем в шаблоне и не может в настоящий момент напрямую создавать псевдонимы шаблонов (будет исправлено в 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
}
Существует еще один возможный gotcha при использовании Derived<T>::Nested
в шаблонах, но, опять же, это проблема с зависимым именем, не связанная с наследованием:
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<T>::B
- напрямую с префиксом
template
, если это зависимый шаблон: A<T>::template f<int>()
- оба, если оба:
typename A<T>::template B<int>
typename
недопустимо в списках базовых классов: template<class T> struct A : B<T>, C<T>::template D<int> {};