【问题标题】:Why does the following not work when the map is const static为什么地图为 const static 时以下内容不起作用
【发布时间】:2016-08-05 08:37:05
【问题描述】:

考虑以下示例:

enum class DOG_TYPE {SHEPHARD, COLLIE,UNKNOWN};

static  const std::map<std::string,DOG_TYPE> dogMap = {
                {"GS",DOG_TYPE::SHEPHARD}
};


DOG_TYPE getDogType(const std::string& dogtype) 
{
    if(dogMap.find(dogtype) != dogMap.end())
    {
        return  dogMap[dogtype];  -->Does not work when std::map is constant
    }
}

int main()
{
DOG_TYPE j = getDogType("GS");
std::cout << int(j);
}

在上面的例子中,语句return dogMap[dogtype];返回错误

error: passing 'const std::map<std::__cxx11::basic_string<char>, DOG_TYPE>' as 'this' argument discards qualifiers [-fpermissive]
         return  dogMap[dogtype];

我想知道为什么会发生这种情况以及为什么不能映射const static

【问题讨论】:

标签: c++ c++11


【解决方案1】:

std::map 上使用operator[] 会创建不存在的对象。所以这是一个只能在允许修改的地图上执行的操作。请改用find

【讨论】:

    【解决方案2】:

    它不起作用,因为std::map 没有声明为constoperator[],因此您不能在const std::map 对象上使用operator[]

    std::map::operator[] 被定义为返回一个 reference 到一个键控值。如果未找到该键,地图将被修改以插入该键的默认值,以便它可以绑定返回的引用。显然,修改const std::map 是行不通的,因此会出现编译器错误。

    要执行您正在尝试的操作,您可以使用std::map::find() 搜索键,而无需为其插入新值。如果找到密钥,您可以取消引用返回的iterator

    如果没有找到键,不要忘记让你的函数返回一个默认值。

    试试这个:

    DOG_TYPE getDogType(const std::string &dogtype) 
    {
        auto iter = dogMap.find(dogtype);
        if (iter != dogMap.end())
            return iter->second;
        return DOG_TYPE::UNKNOWN;
    }
    

    【讨论】:

      【解决方案3】:

      正如其他人所说,operator[] 如果密钥不存在,请修改地图。

      但你可以使用at()

      DOG_TYPE getDogType(const std::string& dogtype) 
      {
          if(dogMap.find(dogtype) != dogMap.end())
          {
              return  dogMap.at(dogtype);
          }
      }
      

      而且,如果您负担得起 getDogType()dogtype 不是 dogMap 中的键时引发异常,那么简单

      DOG_TYPE getDogType(const std::string& dogtype) 
      {
              return  dogMap.at(dogtype);
      }
      

      ps:at() 仅适用于 C++11

      p.s.2:抱歉我的英语不好。

      【讨论】:

      • 同时使用 find()at() 是多余的,因为您将执行 2 次相同的搜索以获得 1 个结果。使用任一 find() at(),而不是两者
      • @RemyLebeau - 你是对的:我的第一个例子是无效的(第二个是有问题的,因为当 OP 可能想要 UNKNOWN 而不是异常时抛出异常)。作为一个借口,我说我的意图只是向 OP 表明 operator[] 它仅在 at() 存在(来自 C++11)和 const 版本时以非常量模式存在。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-23
      • 1970-01-01
      • 2013-02-11
      • 2021-04-28
      • 1970-01-01
      相关资源
      最近更新 更多