解决error C2760错误

起因

在学习《某某编程案例精粹》一书时,使用书中的WestWorldWithMessaging项目代码报错。报错代码段如下:

template <class container>
inline void DeleteSTLContainer(container& c)
{
	//下面这句报错,可能有大佬已经看出哪里错了
	for (container::iterator it = c.begin(); it != c.end(); ++it)
	{
		delete *it;
		*it = NULL;
	}
}

vs2017错误信息如下error C2760: 语法错误: 意外的令牌“标识符”,预期的令牌为“;”

常规解决流程

遂上网查找原因,如果你尝试复制这个错误信息到百度,那么你会得到千篇一律的这种答案
只要在这里把符合模式改为否即可。
答案

换一种方法

当然,我照做之后,问题顺利的解决了。。但是,我突然感到一丝不自然。

所以我去查了微软的官方文档:文档指出这种错误是因为编译器无法理解这段代码。
看起来貌似事件没那么简单,我去stack overflow查了这个错误,找到这样一篇答案,发现如下一句代码。
随后我发出菜鸡的疑问:这句代码是在干嘛的。。

using def = typename x::d<0>;

using的四种用法

参考这篇文章

  1. 命名空间
  2. 作用同typedef
  3. 派生类继承基类后,可以用using声明来改变private字段的可访问性。
  4. 用来对付C++的隐藏规则

很容易看出上述代码用得是第二种用法。

typename

一个看起来很普通的关键字。但我搜索到它的相关定义后,问题便迎刃而解。有兴趣可以读下这篇文章
简单的说这个关键字存在的本来目的是配合模板使用的,你大概看过这样的用法:

// implement strcmp-like generic compare function
// returns 0 if the values are equal, 1 if v1 is larger, -1 if v1 is smaller
template <typename T>
int compare(const T &v1, const T &v2)
{
    if (v1 < v2) return -1;
    if (v2 < v1) return 1;
    return 0;
}

随着一系列改进,它大概可以用来处理这样的例子:

template <class T>
void foo() {
    T::iterator * iter;
    // ...
}

我第一眼看这段代码,想到的就是一个模板里声明了一个迭代器。其实不是,因为iterator也可以是一个名叫iterator的变量名字。
所以这种情况,编译器(版本高一点,大概)会发现这种歧义。出现报错。
而typename还有一种用法就是可以告诉编译器这样一段歧义是一个类型而不是变量。
所以讲到这里,问题的答案很显然了。
下面加一个Prime里面的解释
typename

改进

不用改什么符合模式,只要在container前加一个typename就可以了

template <class container>
inline void DeleteSTLContainer(container& c)
{
	for (typename container::iterator it = c.begin(); it != c.end(); ++it)
	{
		delete *it;
		*it = NULL;
	}
}

最终绕了一个大弯,问题顺利解决。

  • 18
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值