映射的反向迭代,由getter/without copy访问

Reverse iterating of map, which is accessed by getter / without copy

本文关键字:getter without copy 访问 迭代 映射      更新时间:2023-10-16

我有一个类,它读取/解析文件并在映射中存储键值对。

typedef std::map<std::string, const int> Data;
typedef std::map<std::string, const int>::reverse_iterator DataItReverse;

现在我有了一个getter来从"解析器"类inline Data getData() const {return _data;} 中获取数据

一切都很好,直到我想通过有问题的映射进行反向迭代。

for(DataItReverse it_reverse = _parser->getData().rbegin();
    it_reverse != _parser->getData().rend();
    ++it_reverse)
{
    std::cout << it_reverse->first << std::endl;
}

上面的代码以正常顺序迭代(不是反向),当我将数据复制到临时变量时,一切都很好:

Data tmpData = _parser->getData();
for(...)

我想避免复制数据,因为它将是一张大地图。


请注意,_parser是一个指针,因此它内部的数据不会被多次复制

通过迭代到使用迭代器时不存在的临时对象,实际上得到了未定义的行为。

制作一个副本(因为您正确地将其标识为解决方案),或者更改"getter"以返回引用。

inline const Data & getData() const { return _data; }

这实际上是标准做法。您通常不会从getter按值返回复杂的结构,除非它是派生数据(不存储在类中),或者可能在调用后发生更改(例如,多线程环境中需要获取锁才能获得当前状态):

然后,您将不得不使用const迭代器。我倾向于使用auto关键字来避免循环中的混乱:

for( auto it = _parser->getData().rbegin(); it != _parser->getData().rend(); ++it )

要使用非常量迭代器,您需要制作一个副本,或者还提供一个非常量"getter"。这通常不推荐,但可能适合您的目的:

inline Data & getData() { return _data; }