为什么在 return 类型中需要 typename? C++

Why is typename necessary in return type? C++

给定一个模板class带有嵌套节点结构的队列。

为什么这里的 return 类型需要 typename?

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

模板中的嵌套结构节点 class 队列将在 Queue<T>:: 的范围内,没有类型名。

根据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.

但我不明白为什么使用 typename 是合理的?

在解析 return 类型(如问题中定义的)时,我们还不在 Queue<T> 的范围内。如果你写

你的推理是正确的
template<typename T>
auto Queue<T>::test() -> Node* {

}

完全限定函数名的嵌套名称限定符将我们置于当前模板特化的范围内。此处非限定名称查找在当前特化中找到 Node*,其中已知引用类型。

但是在解析问题中的 return 类型时,编译器尚未遇到 "current specialization" ,其中 Node* 可以明确地假定为命名类型。它所看到的只是我们写了一个来自 some 专业化的依赖名称。因此,需要 typename。和我们写

没什么两样
template<typename T>
typename OtherUnrelatedClass<T>::Node* Queue<T>::test() {

}

是正确的。我想补充一个观点。

在以经典函数形式解析 Queue<T>::Node* 时(就像在你的例子中)你还不知道 你在解析什么,你不知道你正在解析函数的 return 类型,这就是为什么你需要明确指定你有一个类型。 (好吧,正如 StoryTeller Down with typename 发布的 link 中所示,您可能知道,但它需要更复杂的解析,即您需要提前扫描以确定您在函数声明中)。

但是在后缀 return 类型中,当您到达 Queue<T>::Node* 时,您已经确定您正在解析一个函数的声明,现在需要一个 return 类型。