Почему typename необходимо указывать в типе возвращаемого значения? C ++ - PullRequest
3 голосов
/ 18 февраля 2020

При наличии класса шаблона Queue с вложенной структурой Node.

Почему здесь требуется typename в возвращаемом типе?

template<typename T>
typename Queue<T>::Node* Queue<T>::test() {}

Вложенная структура Node в классе шаблона Queue будет в области Queue<T>:: без typename.

Согласно Где и почему я должен поставить ключевые слова "template" и "typename"? :

Мы решаем, как компилятор должен это проанализировать. Если t :: x является зависимым именем, то нам нужно добавить префикс к typename, чтобы сказать компилятору, что он должен разобрать его определенным образом.

Но я не понимаю, почему это оправдывает использование typename

Ответы [ 2 ]

6 голосов
/ 18 февраля 2020

При синтаксическом анализе типа возврата (как определено в вопросе) мы пока не находимся в области действия Queue<T>. Ваши рассуждения были бы правильными, если бы вы написали

template<typename T>
auto Queue<T>::test() -> Node* {

}

Вложенный префикс имени полного имени функции ставит нас в рамки текущей специализации шаблона. Здесь поиск безусловного имени находит Node* в текущей специализации, где известно, что он ссылается на тип.

Но при синтаксическом анализе возвращаемого типа в вашем вопросе компилятор еще не столкнулся с «текущей специализацией» где Node* можно однозначно предположить, чтобы назвать тип. Все, что он видит, - это мы пишем зависимое имя из некоторой специализации. Таким образом, typename требуется. Для нас нет ничего необычного в том, чтобы писать

template<typename T>
typename OtherUnrelatedClass<T>::Node* Queue<T>::test() {

}
2 голосов
/ 18 февраля 2020

Ответ StoryTeller правильный. Я хотел бы добавить другую перспективу.

Во время синтаксического анализа Queue<T>::Node* в классической форме функции (как в вашем примере) вы еще не знаете что вы анализируете, вы не Не знаю, что вы анализируете тип возвращаемого значения функции, поэтому вам нужно явно указать, что у вас есть тип. (ну, как показано в ссылке, опубликованной StoryTeller Долой имя типа , вы могли бы знать, но это требует более сложного анализа, т. е. вам нужно сканировать заранее, чтобы определить, что вы находитесь в объявлении функции).

Но в суффиксном типе возврата, когда вы достигаете Queue<T>::Node*, вы уже определили, что анализируете объявление функции, и теперь ожидается возвращаемый тип.

...