You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
template <typename T> classTrap {
public:enum { x }; // #1 x is not a type here
};
template <typename T> classVictim {
public:int y;
voidpoof() {
Trap<T>::x *y; // #2 declaration or multiplication?
}
};
template <> classTrap<void> { // evil specialization!public:using x = int; // #3 x is a type here
};
voidboom(Victim<void> &bomb) { bomb.poof(); }
如果你直接编译,会报错:
main.cc:30:14: error: unexpected type name 'x': expected expression
Trap<T>::x *y; // #2 declaration or multiplication?
^
main.cc:39:38: note: in instantiation of member function 'Victim<void>::poof' requested here
voidboom(Victim<void> &bomb) { bomb.poof(); }
^
1 error generated.
zhangyachen
changed the title
c++11-17 模板核心知识(十五)—— 解析模板之依赖型类型名称与typename Dependent Names of Types
c++11-17 模板核心知识(十五)—— 解析模板之依赖型类型名称(Dependent Names of Types)与typename
Dec 8, 2020
上篇文章c++11-17 模板核心知识(十四)—— 解析模板之依赖型模板名称 Dependent Names of Templates(.template/->template/::template) 介绍了依赖型模板名称,提到关于模板解析有六个大方面:
这篇文章介绍下依赖型类型名称(Dependent Names of Types)。
模板名称的问题及解决
模板中的名称存在一个问题:它们有的时候不能被很好的分类,比如一个模板引用其他模板的名称,因为模板特化的存在,会让问题变得复杂一些。例如:
如果你直接编译,会报错:
这个问题和解决方案在c++11-17 模板核心知识(二)—— 类模板涉及过,这篇文章再展开说一下相关规则。
回到上面的例子,当编译器解析到#2处时,它需要决定
Trap<T>::x
是一个类型还是一个值,这决定了Trap<T>::x *y
是声明一个指针还是做乘法。问题是,在Trap中,
Trap<T>::x
是一个值,但是在全特化版本Trap<void>
中,Trap<T>::x
是一个类型。所以,这种情况实际是依赖模板参数T的,也就是依赖型类型名称(Dependent Names of Types)。C++规定,只有当加上typename关键字后,依赖型类型名称才会被当做类型,否则会被当做一个值。这里typename的意义和声明一个模板时使用的typename是两个意思,所以不能用class来替换typename.
typename规则
当一个名称具备以下性质时,需要在名称前面加typename:
例如:
下面逐一说下上面各个typename的使用场景(有的使用方式是错误的):
X<int>::C
不依赖模板参数,即不是Dependent Name.current instantiation
,这个概念下篇文章会讲到。C++20 typename
是了,这一大堆乱七八糟的规则,谁也不想去记。C++20对typename的规则做了一些改善,有一些场景不再需要typename。详情大家可以参考 : The typename disambiguator for dependent names
(完)
朋友们可以关注下我的公众号,获得最及时的更新:
The text was updated successfully, but these errors were encountered: