我有以下C ++类和方法。我试图从const函数numOutgoing()
中访问私有成员“outgoing”。我对第127-128行与129-130行的行为感到困惑。
第129行:制作副本,以后可以修改,const函数不关心 第130行:获得参考,但vec被定义为const,所以一切都很好。
第127行:我假设正在制作副本,但是我收到编译错误 第128行:相同的编译器错误。
90 class Graph
91 {
92 map<int, vector<int> > outgoing;
93
95 public:
96 Graph(const vector<int> &starts, const vector<int> &ends);
97 int numOutgoing(const int nodeID) const;
99 };
100
120
121 int
122 Graph::numOutgoing(const int nodeID) const
123 {
124 if (outgoing.find(nodeID) == outgoing.end()) {
125 throw invalid_argument("Invalid node Id");
126 }
127 // vector<int> vec = outgoing[nodeID];
128 // const vector<int> &vec = outgoing[nodeID];
129 vector<int> vec = outgoing.at(nodeID);
130 // const vector<int> &vec = outgoing.at(nodeID);
131
132 return vec.size();
133 }
我试图理解为什么Line 127/128给出了以下编译错误:
./templ.cc:128:42: error: passing 'const std::map<int, std::vector<int> >' as 'this' argument of 'std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const key_type&) [with _Key = int; _Tp = std::vector<int>; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, std::vector<int> > >; std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type = std::vector<int>; std::map<_Key, _Tp, _Compare, _Alloc>::key_type = int]' discards qualifiers [-fpermissive]
以下是operator []的原型和“map”类中的方法。
mapped_type& operator[] (const key_type& k); <======
mapped_type& operator[] (key_type&& k);
mapped_type& at (const key_type& k);
const mapped_type& at (const key_type& k) const;
如果有人能帮我理解编译错误,真的很感激。问题可能是operator[]
没有返回const
类型吗?如果是,那么operator[]
和at
不等同,对吗?
答案 0 :(得分:3)
您的问题是,因为numOutgoing
函数是const,所以它只能调用类成员上的const函数。在这种情况下,只有const mapped_type& at (const key_type& k) const;
有效。
您还可以保留const_iterator
outgoing.find(nodeID)
并取消引用以获取对子矢量的const访问权。
答案 1 :(得分:3)
这是因为方法
int Graph::numOutgoing(const int nodeID) const
是const
,而operator[]
不是常量。这是因为一个设计决定:如果有人试图访问operator[]
不存在的密钥,那么它会创建它,从而修改std::map
。
要解决您的问题,请使用map<int, vector<int> >::const_iterator result = outgoing.find(nodeID);
然后,如果它不在end()
,您只需使用result->first
访问密钥,使用result->second
访问该值。
答案 2 :(得分:2)
如果有人能帮我理解编译错误,真的很感激。问题是“operator []”不会返回“const”类型吗?如果是这样,那么“operator []”和“at”不等同,对吗?
是的,operator[]
和at
完全不相同。
at
只会返回一个值,因此它可以是const
。如果不存在此类元素,则抛出类型std::out_of_range
的异常。
operator[]
将永远不会抱怨,因为它会尝试创建一个新元素。选择此行为是为了:
std::map<int, int> x;
x[0] = 1;
是可能的。
答案 3 :(得分:1)
问题是operator []是不可靠的。调用者可以使用它返回的非const引用来修改地图内容,因此该运算符未标记为const。