typedef для квалифицированных зависимых типов

Я прочитал это хорошее резюме того, как используется ключевое слово typename в C ++: http://pages.cs.wisc.edu/~driscoll/typename.html

Тем не менее я задаюсь вопросом о конкретном примере:

template<typename T> class Outer{
public:
class Inner1{
T t;
};
class Inner2{
int t;
};
};

template<typename T> void foobar(void)
{
std::list<Outer<T>::Inner1> l;
}

Из приведенного выше текста я понимаю, что мне нужно

std::list<typename Outer<T>::Inner1> l;

поскольку Inner1 является одновременно квалифицированным и зависимым.

Но: Inner2 также требует имя типа, которое смущает меня:
Во-первых, кажется довольно ясным, что Inner2 является типом (ну, это уже ясно для Inner1). Во-вторых, Inner2 вообще не зависит от T. Для всех возможных Ts, Inner2 будет одинаковым (тип)!

Нужен ли мне typedef, как только я использую квалифицированный тип из шаблона? Зависит ли это от параметра шаблона или нет?

1

Решение

Ваше второе предположение неверно. Inner2 делает зависит от T, так как каждый Outer имеет другой Inner2. Это становится понятным, если вы специализируете Outer:

template<> class Outer<char>{
public:
class Inner1{
T t;
};
typedef int Inner2;
};

И даже если ты не специализируешься, Outer<float>::Inner2 а также Outer<long>::Inner2 могут иметь одинаковое расположение, элементы, имена и т. д., но они не одного типа! Подумайте о доступе — Outer<long>::Inner2 имеет доступ к Outer<long>приватные члены, Outer<float>::Inner2 не.

В следующей специализации Inner2 даже не тип:

template<> class Outer<long double>{
public:
char Inner2(int);
};
3

Другие решения

Outer<T>::Inner2 зависит от типа T в том смысле, что компилятор не знает, что за вещь Inner2 это — будь то тип или, например, член статических данных. Так что да, вам нужно сказать компилятору, что это за использование typename здесь, потому что по умолчанию предполагается, что это не типовой элемент (например, элемент статических данных, имя метода, enum значение).

(Это верно для C ++ 03 — я предполагаю, что правила для этого не были изменены в C ++ 11.)

1

По вопросам рекламы [email protected]