在模板定义中要求类型名的原因

Reason for requiring typename in a template definition

本文关键字:类型 定义      更新时间:2023-10-16

可能的重复项:
我必须在何处以及为什么必须在依赖名称上放置"模板"和"类型名称"?

这是问题的一个具体例子:正式地,typename是干什么用的?

我问的是编译器不知道以下类型的具体原因:

#include <set>
#include <vector>
template<typename T>    // T is a type, right?
void f(const char name[], const std::vector<T>& foo) // typename NOT needed here
{
  for(std::set<T>::iterator itr =  // here, it is needed

如果我声明:

std::set<int>::iterator itr; // no problem

上面清楚地定义了T是一种类型,那么为什么typename在一种类型中是必需的,而不是另一种呢?

虽然你已经链接到一个完整的答案,但有很多东西需要涉足。 所以 - 尽可能简单地说 - 关键是编译器确实知道T是你所说的一种类型,但是使用该信息,甚至已经看到了包含的源代码std::set,它无法确定set<T>内的iterator标识符是否会命名一个类型, 函数或变量。 这可能看起来令人惊讶,因为如果您查看set<>模板,您可以解决它,但请记住,在编译器解析f<>()模板和实例化之前之间的某个地方,可能会指定一个专门用于set<T>的专用化,该专用化使用非类型的标识符,或者干脆完全缺少它。

因此,typename 关键字只是告诉编译器,嘿 - 无论发生什么,您都可以期望iterator命名一个类型,并在此基础上对f<>()模板代码执行一些验证,而无需等待看到实例化。