【问题标题】:error C2760: syntax error: unexpected token 'identifier', expected ';' at map iterator [duplicate]错误 C2760:语法错误:意外标记“标识符”,应为“;”在地图迭代器[重复]
【发布时间】:2019-03-27 16:03:50
【问题描述】:

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

似乎迭代器类型未在编译时定义。有没有办法解决这个问题?

【问题讨论】:

  • use of dependent type name must be prefixed with 'typename'.
  • 您正在使用map,就好像它是vector。如果index 是关键,您可以使用地图operator[]
  • 你只需要把typename放在std::map&lt;std::string, _Value&gt;::iterator itr之前
  • 如何在 std::map 之前使用 typename<:string _value>::iterator itr ?
  • 强制性注释:使用_Value 作为标识符是未定义的行为。所有以下划线和大写字母开头的标识符都保留用于实现(与任何以两个下划线开头的标识符一样)。

标签: c++


【解决方案1】:

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

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

auto itr = this->begin();

【讨论】:

    【解决方案2】:

    错误消息准确地告诉你你可以做什么:

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

    ……但不是你必须这样做的原因。

    简而言之,这是 C++ 的一个怪癖,与模板和所谓的“依赖名称”有关。因为_Value 是一个模板参数,并且因为存在模板特化,所以C++ 不能确定std::map&lt;std::string, _Value&gt; 有一个成员类型iterator,直到稍后在解析过程中。因此,您的声明格式不正确,因为即使它眯着眼睛,编译器也不能完全将其视为声明。 typename 说“这将是一种类型,我保证”然后一切都很好(只要它确实是一种类型!)。

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

    或者,使用auto 代替,让您的代码更好,同时解决问题:

    auto itr = this->begin();
    

    顺便说一句,您的代码表明您使用了错误的容器,GetItem 应该是 const,您应该使用 cbegin() 而不是 begin()(尽管如果您按照const 建议)和std::advance 已经存在……

    【讨论】:

      【解决方案3】:

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

      auto itr = this->begin();
      

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

      进一步说明:GetItem 也可以使用const_iterator,因此auto itr = this-&gt;cbegin(); 将是一个改进。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-09-03
        • 2021-09-15
        • 2014-07-25
        • 1970-01-01
        • 2015-05-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多