mirror of
https://github.com/CnTransGroup/EffectiveModernCppChinese.git
synced 2025-01-30 13:50:28 +08:00
Update item9.md
This commit is contained in:
parent
ce3eee7006
commit
3393933fa3
@ -53,7 +53,7 @@ template<typename T>
|
|||||||
class Widget { //Widget<T>含有一个
|
class Widget { //Widget<T>含有一个
|
||||||
private: //MyAllocLIst<T>对象
|
private: //MyAllocLIst<T>对象
|
||||||
typename MyAllocList<T>::type list; //作为数据成员
|
typename MyAllocList<T>::type list; //作为数据成员
|
||||||
...
|
…
|
||||||
};
|
};
|
||||||
````
|
````
|
||||||
这里`MyAllocList<T>::type`使用了一个类型,这个类型依赖于模板参数`T`。因此`MyAllocList<T>::type`是一个依赖类型(*dependent type*),在C++很多讨人喜欢的规则中的一个提到必须要在依赖类型名前加上`typename`。
|
这里`MyAllocList<T>::type`使用了一个类型,这个类型依赖于模板参数`T`。因此`MyAllocList<T>::type`是一个依赖类型(*dependent type*),在C++很多讨人喜欢的规则中的一个提到必须要在依赖类型名前加上`typename`。
|
||||||
@ -68,7 +68,7 @@ template<typename T>
|
|||||||
class Widget {
|
class Widget {
|
||||||
private:
|
private:
|
||||||
MyAllocList<T> list; //没有“typename”
|
MyAllocList<T> list; //没有“typename”
|
||||||
... //没有“::type”
|
… //没有“::type”
|
||||||
};
|
};
|
||||||
````
|
````
|
||||||
对你来说,`MyAllocList<T>`(使用了模板别名声明的版本)可能看起来和`MyAllocList<T>::type`(使用`typedef`的版本)一样都应该依赖模板参数`T`,但是你不是编译器。当编译器处理`Widget`模板时遇到`MyAllocList<T>`(使用模板别名声明的版本),它们知道`MyAllocList<T>`是一个类型名,因为`MyAllocList`是一个别名模板:它**一定**是一个类型名。因此`MyAllocList<T>`就是一个**非依赖类型**(*non-dependent type*),就不需要也不允许使用`typename`修饰符。
|
对你来说,`MyAllocList<T>`(使用了模板别名声明的版本)可能看起来和`MyAllocList<T>::type`(使用`typedef`的版本)一样都应该依赖模板参数`T`,但是你不是编译器。当编译器处理`Widget`模板时遇到`MyAllocList<T>`(使用模板别名声明的版本),它们知道`MyAllocList<T>`是一个类型名,因为`MyAllocList`是一个别名模板:它**一定**是一个类型名。因此`MyAllocList<T>`就是一个**非依赖类型**(*non-dependent type*),就不需要也不允许使用`typename`修饰符。
|
||||||
@ -78,7 +78,7 @@ private:
|
|||||||
举个例子,一个误入歧途的人可能写出这样的代码:
|
举个例子,一个误入歧途的人可能写出这样的代码:
|
||||||
|
|
||||||
````cpp
|
````cpp
|
||||||
class Wine { ... };
|
class Wine { … };
|
||||||
|
|
||||||
template<> //当T是Wine
|
template<> //当T是Wine
|
||||||
class MyAllocList<Wine> { //特化MyAllocList
|
class MyAllocList<Wine> { //特化MyAllocList
|
||||||
@ -87,7 +87,7 @@ private:
|
|||||||
{ White, Red, Rose }; //"enum class"
|
{ White, Red, Rose }; //"enum class"
|
||||||
|
|
||||||
WineType type; //在这个类中,type是
|
WineType type; //在这个类中,type是
|
||||||
... //一个数据成员!
|
… //一个数据成员!
|
||||||
};
|
};
|
||||||
````
|
````
|
||||||
就像你看到的,`MyAllocList<Wine>::type`不是一个类型。如果`Widget`使用`Wine`实例化,在`Widget`模板中的`MyAllocList<Wine>::type`将会是一个数据成员,不是一个类型。在`Widget`模板内,`MyAllocList<T>::type`是否表示一个类型取决于`T`是什么,这就是为什么编译器会坚持要求你在前面加上`typename`。
|
就像你看到的,`MyAllocList<Wine>::type`不是一个类型。如果`Widget`使用`Wine`实例化,在`Widget`模板中的`MyAllocList<Wine>::type`将会是一个数据成员,不是一个类型。在`Widget`模板内,`MyAllocList<T>::type`是否表示一个类型取决于`T`是什么,这就是为什么编译器会坚持要求你在前面加上`typename`。
|
||||||
|
Loading…
Reference in New Issue
Block a user