我有这样的类:
class C {
private:
std::unordered_map<char, int> m = {{'a', 1}, {'b', 2}, {'c', 3}};
public:
int operator[](const char& key) const {
return m.find(key)->second;
}
};
是否可以在不修改类的情况下迭代映射的元素?
我想要这样的东西:
for (auto x: c) {
// x -> a map element
}
不,范围循环不使用operator[]
的定义
for ( range_declaration : range_expression ) loop_statement
是不是像以前一样对待(不引入__names
(
{
auto && __range = range_expression ;
auto __begin = begin_expr ;
auto __end = end_expr ;
for ( ; __begin != __end; ++__begin) {
range_declaration = *__begin;
loop_statement
}
}
begin_expr
和end_expr
规则如下:
- 如果
range_expression
是数组类型的表达式,则begin_expr
__range
,end_expr
(__range + __bound)
, 其中__bound
是数组中元素的数量(如果数组 大小未知或类型不完整,程序是 格式错误(- 如果range_expression是类类型的表达式,则
C
该表达式同时具有名为begin
的成员和名为end
的成员(无论 此类成员的类型或可访问性(,则begin_expr
__range.begin()
和end_expr
是__range.end()
;- 否则,
begin_expr
begin(__range)
,end_expr
end(__range)
,这是通过依赖于参数的查找(非 ADL 不执行查找(。
对你的类进行一个简单的更改就足够了,那就是添加begin
和end
,委派给m.begin()
和m.end()
class C {
private:
std::unordered_map<char, int> m = {{'a', 1}, {'b', 2}, {'c', 3}};
public:
int operator[](const char& key) const {
return m.find(key)->second;
// return m.at(key); or return m[key]; are both safer than this
}
std::unordered_map<char, int>::iterator begin() {
return m.begin();
}
// overloaded on the constness of "this"
std::unordered_map<char, int>::const_iterator begin() const {
return m.begin();
}
std::unordered_map<char, int>::iterator end() {
return m.end();
}
// overloaded on the constness of "this"
std::unordered_map<char, int>::const_iterator end() const {
return m.end();
}
};
No.
除了其他人已经涵盖的 ranged-for 专门施加的约束之外,您的类不会公开任何方法来了解映射中的哪些元素,甚至不会公开第一个或最后一个元素键。它不公开任何迭代器。它只是没有公开足够的信息来执行迭代。
如果一个类提供迭代器,即如果begin(c)
和end(c)
返回迭代器(或c.begin()
和c.end()
(,则可以迭代。您的类不提供迭代器,并且无法在类外部实现迭代器,因为内部映射是私有的。
所以,答案是否定的,类确实需要修改。