如何迭代重载运算符 [] 的类?



我有这样的类:

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_exprend_expr规则如下:

  • 如果range_expression是数组类型的表达式,则begin_expr__rangeend_expr(__range + __bound), 其中__bound是数组中元素的数量(如果数组 大小未知或类型不完整,程序是 格式错误(
  • 如果range_expression是类类型的表达式,则C该表达式同时具有名为begin的成员和名为end的成员(无论 此类成员的类型或可访问性(,则begin_expr__range.begin()end_expr__range.end();
  • 否则,begin_exprbegin(__range)end_exprend(__range),这是通过依赖于参数的查找(非 ADL 不执行查找(。

对你的类进行一个简单的更改就足够了,那就是添加beginend,委派给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()(,则可以迭代。您的类不提供迭代器,并且无法在类外部实现迭代器,因为内部映射是私有的。

所以,答案是否定的,类确实需要修改。

相关内容

  • 没有找到相关文章

最新更新