仅当使用unordered_map而不是向量时,将const作为此参数传递才会丢弃限定符

据我所知,调用非const方法恒定的对象作为解释给出了一个错误这里。这个问题虽然涉及相同的错误,但不是重复的,因为它不是关于非常量方法。

这次我有一个最小的可重现示例:

// Example program
#include <iostream>
#include <string>
#include <vector>
#include <unordered_map>

class Something
{
public:
    int m_value;
    Something(): m_value{0} { myVector.push_back(1); myMap["hello"]=3; }
    void setValue(int value) { m_value = value; }
    int getValue() { return m_value ; }
    //int getValue(const int value){ return myVector[value]  ;  }  //<-- this gives an error (just reference)
    int getValue(const int value)const { return myVector[value];    }
    //int getValue2(const std::string &name) {return myMap[name];   }  //<--- this gives an error (just reference)
    int getValue2(const std::string &name) const {return myMap[name];   } //HERE this gives an error (this question)
    
   std::vector<int> myVector;
   std::unordered_map<std::string,int> myMap;
   
};
 
int main()
{
    const Something something{}; // calls default constructor
                
    int l= something.getValue(0);
    std::cout<<l<<std::endl;
    
    l= something.getValue2("hello");  //<-- HERE the error
    std::cout<<l<<std::endl;
    
    return 0;
}

在注释中,有两个方法声明说明了非常量方法的要点。我把它们留在那里以供参考。这个问题不在他们之上。

你看到getValue返回向量元素的 const方法了吗?这没有问题。现在看到getValue2应该返回无序映射元素的 const方法了吗?即使它是一个常量方法,它也会产生错误

In member function 'int Something::getValue2(const string&) const':
17:68: error: passing 'const std::unordered_map<std::basic_string<char>, int>' as 'this' argument of 'std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::mapped_type& std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator[](const key_type&) [with _Key = std::basic_string<char>; _Tp = int; _Hash = std::hash<std::basic_string<char> >; _Pred = std::equal_to<std::basic_string<char> >; _Alloc = std::allocator<std::pair<const std::basic_string<char>, int> >; std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::mapped_type = int; std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::key_type = std::basic_string<char>]' discards qualifiers [-fpermissive]

我的问题是:为什么只有无序映射传递常量,因为索引会产生此错误?

编辑:感谢非常有用的答案。我将课程修改为

// Example program
#include <iostream>
#include <string>
#include <vector>
#include <unordered_map>

class Something
{
public:
    int m_value;
    Something(): m_value{0} { myVector.push_back(1); myMap["hello"]=3; }
    void setValue(int value) { m_value = value; }
    int getValue() { return m_value ; }
    //int getValue(const int value){ return myVector[value]  ;  }  //<-- this gives an error
    int getValue(const int value)const { return myVector[value];    }
    //int getValue2(const std::string &name) {return myMap[name];   }  //<--- this gives an error
   //this will generate an exception if name is not in the map
    int getValue3(const std::string &name) const {
              //return myMap[name]; 
                return myMap.at(name);}
    int getValue2(const std::string &name) const {
            auto iter = myMap.find(name);
            return (iter != myMap.end()) ? iter->second : 0;
}
    
    
   std::vector<int> myVector;
   std::unordered_map<std::string,int> myMap;
   
};

回答

const-qualified 版本getValue2只能const访问 的成员Something。这意味着它将看到myMap类型const std::unordered_map<std::string,int>并且您不能在 上调用任何非const成员函数myMap。这operator[]是一个非const成员函数(它不能被 make const,因为它有时必须插入一个值初始化的条目,即当在映射中找不到键时)所以你会得到关于丢弃限定符的错误消息。要解决此问题,您可以使用.at(name)代替[name]. 如果name在地图中找不到,这将引发异常。


以上是仅当使用unordered_map而不是向量时,将const作为此参数传递才会丢弃限定符的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>