编译错误need 'typename' before *** because *** is a dependent scope 浅析
来源:互联网 发布:ios 彩票项目源码 编辑:程序博客网 时间:2024/04/30 00:00
例子
template<typename T>void func(){ vector<int>::iterator it_int; vector<T>::iterator it;}
编译后提示:[Error] need ‘typename’ before ‘std::vector::iterator’ because ‘std::vector’ is a dependent scope
上面的用法想必应该很常见吧, 这样写在VC下编译通过, 然而在gcc下编译是会出现如上错误的. 在google上大概搜了下, stackoverflow倒是有解析, 但中文的解析就比较零散, 所以在这里写一些个人的理解, 希望能帮到一些像我一样英文不太好的同学, 顺便也帮助一下自己理解模板的概念…
概念
要想搞清楚这个问题首先需要区分两个概念
(以下概念均为个人浅显的理解, 如有错误敬请指正)
模板 : 模板不是函数或类, 正如字面理解, 它并不是一个可以拿来使用的实在的对象, 也就是没有实体, 用来根据你所给它的类型参数帮你生成一个可以拿来使用的实例对象.
模板实例化 : 给模板以类型参数之后, 模板创建实例对象的过程.
模板特化 : 针对某些特定的具体类型, 对模板进行修改使其对于该类型的实例对象的行为不同.
分析
首先注意到, vector<int>::iterator it_int;
是可以通过的, 而用模板参数类型T声明的vector<T>::iterator it;
却不能通过, 它们的关键区别在于vector<int>
是实例化之后的一个实在的类型, 而vector<T>
还是一个模板类型, 如何实例化还需要取决于外部实际传进来的类型参数T.
正如编译器的错误提示because ‘std::vector’ is a dependent scope, dependent scope就指出了这个类型还需要依赖别的条件, 也就是传进来的类型参数, 与上面的分析是一致的.
原因
但是为什么编译器不能直接根据模板类型的定义来实现这个声明呢?
原因在于编译器无法识别std::vector<T>::iterator
这个名称是一个成员变量还是一个类型. 因为假如vector这个类被特化了, 如在vector类定义的文件内有下列代码:
template <>class vector<char>{ int iterator; // ..detail omitted}
那么std::vector<char>::iterator
这个名称就是一个成员变量了, 把它当做类型就不能在适用了.
因此, 为了防止出现这样的歧义, 正如编译器提示的, 需要在std::vector<char>::iterator
之前加一个关键字typename
来显式地说明它是一个类型而, 非成员变量.
参考
“Where and why do I have to put the “template” and “typename” keywords”
“Nested templates with dependent scope”?
- 编译错误need 'typename' before *** because *** is a dependent scope 浅析
- typename "dependent scope"
- error: need 'typename' before '.......'的解决方法
- dependent scope
- IOS编译警告之:performSelector may cause a leak because its selector is unknown
- Cannot modify the return value of ...,because it is not a variable 错误分析与解决
- Flex编译错误 - Whitespace is not allowed before an XML Processing Instruction
- A dependent property in a ReferentialConstraint is mapped to a store-generated column. Column:
- Before Anything, an Architect Is a Developer
- Springmvc rest 传递json报415错误(The server refused this request because the request entity is in a forma
- ssh登录问题出现Pseudo-terminal will not be allocated because stdin is not a terminal错误
- rapidsvn 编译错误: OnOK is not a member of CheckoutDlg
- c++ 编译错误is not a static member of ...
- Qt编译错误: 'UnicodeUTF8' is not a member of 'QApplication'
- 编译错误syntax error : missing ';' before 'type'
- 编译错误syntax error : missing ';' before 'type'
- 编译错误syntax error : missing ';' before 'type'
- 编译错误:commands commence before first target
- ubuntu中怎样添加或删除一个PPA源
- 实现标题固定,上滑覆盖标题的效果
- 一、计算机、计算与计算思维
- 欢迎使用CSDN-markdown编辑器
- MATLAB 自编3*3中值滤波(含边缘)
- 编译错误need 'typename' before *** because *** is a dependent scope 浅析
- 走进HCI这个家
- yii2 model validate
- Mysql+Dos总结
- linux
- 文章标题
- ubuntu文件系统结构讲解
- Android Studio安装butterknife插件,让人无语的事情
- 基于Exynos4412 cortex A9开发板的无线网卡驱动移植过程