成功解决“C7510 “某某”: 类型 从属名称的使用必须以“typename”为前缀“
🦄个人主页:修修修也
⚙️操作环境:Visual Studio 2022
编辑
目录
📌问题描述
我们在使用C++编写程序,特别是使用template定义模板时经常会遇到编译 器 报错“类型 从属名称的使用必须以“typename”为前缀”,如图:
编辑
遇到这种情况该如何解决?(不想看原理分析可以直接移步第三部分解决办法)
📌原因分析
下面我们会假设一个简单的场景,帮助我们更简单的分析问题
假设我们有一个场景,就是需要写一个函数Print()来打印vector<int>类型内的数据内容还需要打印list<int>类型内的数据内容,我们很自然的将Print()函数写成了模板,代码如下:
template<class Container>
void Print(const Container& v)
{
Container::const_iterator it = v.begin();
auto it = v.begin();
while (it != v.end())
{
cout << *it << " ";
++it;
}
cout << endl;
}
int main()
{
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
Print(v);
list<int> lt;
lt.push_back(1);
lt.push_back(2);
lt.push_back(3);
Print(lt);
return 0;
}
编译运行,却报错了:
编辑
造成这种现象的原因是其中这行代码造成了歧义:
Container::const_iterator it = v.begin();
原因是因为编译器不确定Container::const_iterator是类型还是成员变量:
• Container::const_iterator是类型的情况:编辑
• Container::const_iterator可能是成员变量的情况:编辑这种情况就相当于与你写了这样一段代码:
• int a;
a b = 2;
编辑
可以很清晰的明白,变量名是不可以当作类型的,如果是这种情况那么编译器就一定要在运行程序的第二步就直接报语法错误:编辑
此时编译器在第二步编译时就会不知道如何处理这段代码,到底是把Container::const_iterator当作类型编译通过进行下一步汇编还是报语法错误?这就会导致歧义!
注意,即便我们在定义模板参数时使用typename定义,也会报错:编辑
📌解决办法
在搞清楚了编译器为何会报错之后,我们的解决方法也非常简单:
正确做法是在container::const_iterator前面加上typename,直接告诉编译器这就是一个类型,在后面等模板实例化之后再去找,不要直接报语法错误:
typename Container::const_iterator it = v.begin();
编辑 当然这种情况也可以通过直接用auto关键字来反推it的类型来解决,这样编译器就知道到时候要靠后面的v.begin()来反推it, 就不会在语法阶段报错:
auto it = v.begin();
但是auto也不是万能的,如下面这种类模板的声明的时候就不能用auto反推:编辑
我们在定义模板参数时使用typename定义,遇到这种报错解决方法也同上,加上typename或者换成auto就行:编辑
结语
希望这篇关于 解决"类型 从属名称的使用必须以“typename”为前缀"问题 的博客能对大家有所帮助,欢迎大佬们留言或私信与我交流.
学海漫浩浩,我亦苦作舟!关注我,大家一起学习,一起进步!
相关文章推荐
编辑
- 点赞
- 收藏
- 关注作者
评论(0)