错误C2760:语法错误:意外的令牌'标识符',预期为';'在地图迭代器上

时间:2018-10-23 12:05:40

标签: c++

我创建了一个继承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'

似乎迭代器类型未在编译时定义。有解决此问题的解决方案吗?

3 个答案:

答案 0 :(得分:4)

您可以通过以下方式对其进行修复:

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

auto itr = this->begin();

答案 1 :(得分:1)

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

auto itr = this->begin();

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

进一步的说明:GetItem也可以使用const_iterator,因此auto itr = this->cbegin();会有所改进。

答案 2 :(得分:1)

错误消息告诉您确切的操作:

   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已经存在……