Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is typename necessary in return type? C++

Given a template class Queue with a nested Node struct.

Why is typename needed in the return type here?

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

The nested struct Node in the template class Queue would be in the scope of Queue<T>:: without typename.

According to Where and why do I have to put the "template" and "typename" keywords?:

We decide how the compiler should parse this. If t::x is a dependent name, then we need to prefix it by typename to tell the compiler to parse it in a certain way.

But I don't see why it justifies using typename?

like image 986
csguy Avatar asked Dec 18 '22 14:12

csguy


2 Answers

While parsing the return type (as defined in the question) we are not in the scope of Queue<T> yet. Your reasoning would be correct if you were to write

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

}

The nested name qualifier of the fully qualified function name puts us into the scope of the current template specialization. Here unqualified name lookup finds Node* in the current specialization, where it is known to refer to a type.

But while parsing the return type in your question the compiler hasn't yet encountered the "current specialization" where Node* can be unambiguously assumed to name a type. All it sees is us writing a dependent name from some specialization. As such, typename is required. It's no different to us having to write

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

}
like image 135
StoryTeller - Unslander Monica Avatar answered Dec 20 '22 02:12

StoryTeller - Unslander Monica


StoryTeller's answer is correct. I would like to add another perspective.

While parsing Queue<T>::Node* in the classical function form (like in your example) you don't know yet what you are parsing, you don't know you are parsing the return type of a function, that's why you need to explicitly specify you have a type. (well, as shown in the link posted by StoryTeller Down with typename you could know, but it requires a more complex parsing i.e. you need to scan ahead to determine you are in a function declaration).

But in the suffix return type when you reach Queue<T>::Node* you already determined you are parsing the declaration of a function and now a return type is expected.

like image 35
bolov Avatar answered Dec 20 '22 02:12

bolov