我知道调用一个非常量方法到一个常量对象会产生错误,如解释的那样 here .这个问题虽然涉及相同错误,但不是重复问题,因为它与非常量方法无关。
这次我有一个最小的可重现示例:
// 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;
}
在注释中有两个方法声明说明了关于非常量方法的要点。我把它们留在那里以供引用。这个问题不在他们之上。
您看到返回 vector 元素的 const getValue
方法了吗?这没有问题。
现在看到应该返回无序 map 元素的 const getValue2
方法了吗? 尽管它是一个常量方法,但它会产生错误
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]
我的问题是:为什么只有无序映射传递常量作为索引会产生这个错误?
编辑: 感谢非常有用的答案。我将类(class)修改为
// 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
-合格版本getValue2
只有 const
访问Something
的成员.这意味着它将看到 myMap
类型为 const std::unordered_map<std::string,int>
你不能调用任何非 const
myMap
上的成员函数. operator[]
是非 const
成员函数(不能创建 const
,因为它有时必须插入一个值初始化的条目,即当在映射中找不到键时)所以你会收到关于丢弃限定符的错误消息。要解决这个问题,您可以使用 .at(name)
而不是 [name]
.如果 name
,这将引发异常在 map 上找不到。
关于c++ - 仅当使用 unordered_map 而不是 vector 时,将 const 作为此参数传递才会丢弃限定符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65082000/