错误 C2760:语法错误:映射迭代器上意外的标记"标识符",预期的";"

error C2760: syntax error: unexpected token 'identifier', expected ';' at map iterator

本文关键字:错误 标识符 C2760 迭代器 映射 意外 语法      更新时间:2023-10-16

我创建了一个继承std::map的类,并试图使用方法获取特定索引的值。

#define MYAPI_EXPORTS
#ifdef MYAPI_EXPORTS  
#define MY_API __declspec(dllexport)
#else  
#define MY_API __declspec(dllimport)   
#endif
template<class _Value>
class MY_API MyDictionary : public std::map<std::string, _Value>
{
_Value GetItem(int index)
{
std::map<std::string, _Value>::iterator itr = this->begin(); //compile error at this line
int c = 0;
while (c < index)
{
itr++;
c++;
}
return itr->second;
}
};

'std::map::iterator itr' 这一行在编译时显示错误。

错误是

error C2760: syntax error: unexpected token 'identifier', expected ';'
error C7510: 'iterator': use of dependent type name must be prefixed with 'typename'

似乎在编译时没有定义迭代器类型。有什么解决方案可以解决这个问题吗?

你可以通过以下方式修复它:

typename std::map<std::string, _Value>::iterator itr = this->begin();

auto itr = this->begin();

错误消息会准确地告诉您可以执行的操作:

typename std::map<std::string, _Value>::iterator itr = this->begin();
// ^^^^^^^^^

......但不是为什么你必须这样做。

简而言之,这是与模板和所谓的"从属名称"相关的C++怪癖。由于_Value是模板参数,并且存在模板专用化,因此C++直到分析过程的稍后阶段才能确定std::map<std::string, _Value>是否具有成员类型iterator。因此,您的声明格式不正确,因为编译器即使眯着眼睛也无法将其视为声明。typename说"这将是一种类型,我保证",然后一切都很好(只要它确实变成了一种类型!

你可能认为这应该是C++的问题,而不是你的问题,你可能是对的,但事实就是如此。您可以搜索有关此的更多信息,或者只是想当然地认为,当编译器告诉您编写typename时,您编写typename

或者,通过使用auto来使您的代码更好并同时解决问题:

auto itr = this->begin();

顺便说一下,你的代码表明你使用了错误的容器,GetItem应该是const的,你应该使用cbegin()而不是begin()(尽管如果你遵循const建议,这是为你做的(,std::advance已经存在......

要修复错误,您可以按照编译器给出的提示进行操作,也可以将行更改为

auto itr = this->begin();

虽然过度使用auto是值得怀疑的,但通常认为迭代器类型是可以的;返回begin()end()成员函数的类型很常见(有时很复杂(,以至于不键入确切的类型。

另一个旁注:GetItem也可以使用const_iterator,因此auto itr = this->cbegin();将是一个改进。