> For the complete documentation index, see [llms.txt](https://jerakrs.gitbook.io/effective_c/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://jerakrs.gitbook.io/effective_c/chapter7/section42.md).

# 条款42：了解 typename 的双重含义

Understand the two meanings of typename.

声明 template 参数时，前缀关键字 class 和 typename 是没有区别的：

```cpp
template<class T> class Widget;
template<typename T> class Widget;
```

#### 必须使用 typename 的时候

* 从属名称（dependent names）：template 内相依赖于某个 template 参数；
* 嵌套从属名称（nested dependent name）：从属名称在 class 内呈嵌套状；

```cpp
template<typename C>
void prin2nd(const C& container) {
    C::const_iterator* x;    // 嵌套从属名称
}
```

嵌套从属名称有可能导致解析困难，因为 `C::const_iterator` 可能不是个类型，它有可能是位于 C 里面的一个 static 变量或是一个全局变量。所以在 template 中涉及一个嵌套从属类型名称时，必须在紧邻它的前一个位置放上关键字 typename。不过 typename 不可以出现在 base classes list 内的嵌套从属类型名称之前，也不可再 member initialization list 中作为 base class 修饰符：

```cpp
template<typename T>
class Derived: public Base<T>::nested {              // base class list 中；
public:
    explicit Derived(int x): Base<T>::Nested(x) {    // mem. init. list 中；
        typename Base<T>::Nested temp;
    }
};
```
