gpt4 book ai didi

c++ - 使用临时对象将迭代器获取到 STL 容器时出现细微错误 : how to avoid it?

转载 作者:行者123 更新时间:2023-11-30 03:02:56 25 4
gpt4 key购买 nike

让我们考虑一下这个类:

class X {
std::map<uint32_t, uint32_t> _map;
public:
X() { /* Populate the map */ }

std::map<uint32_t, uint32_t> getTheMap() { return _map; }
};

还有这个有问题的代码:

X x;
// Statement 1
std::map<uint32_t, uint32_t>::const_iterator it = x.getTheMap().begin();
// Statement 2
std::map<uint32_t, uint32_t>::const_iterator et = x.getTheMap().end();

for (; it != et; it++) {
/* Access the map using the iterator it */
}

错误的部分是,在 Statement 1Statement 2 中,我得到了一个指向临时对象的迭代器,该对象将在每一个陈述。因此,for() 循环内的行为是未定义的。

getTheMap() 方法的正确用法应该是这样的:

std::map<uint32_t, uint32_t> map = x.getTheMap();
std::map<uint32_t, uint32_t>::const_iterator it = map.begin();
std::map<uint32_t, uint32_t>::const_iterator et = map.end();

for (/* [...] */)

必须注意类 X 有一些严重的设计问题:

  1. _map 应该更好地封装在类中(读写访问),因此可以避免 getTheMap() 方法
  2. 如果确实需要 getTheMap() 方法,它可以返回对 _map 的引用

但是,如果“按原样”给定 X 类(<-- 请参阅下面的编辑),是否有办法阻止用户将迭代器获取到临时值?

编辑:类 X 可以更改,但 getTheMap 方法应该存在并按值返回。但是我也在考虑编译器警告。

最佳答案

一种可能是使用这样的包装器:

class X {
typedef std::map<uint32_t,uint32_t> Map;
Map _map;

struct MapWrap {
const Map &mapref;

MapWrap(const Map &mapref_arg)
: mapref(mapref_arg)
{
}

operator Map() const { return mapref; }
};


public:
MapWrap getTheMap()
{
return MapWrap(_map);
}
};

所以你得到这个:

X x;
std::map<uint32_t,uint32_t>::const_iterator iter = x.getTheMap().begin(); // error
std::map<uint32_t,uint32_t> m = x.getTheMap(); // no error

这可以防止意外使用像 map 这样的临时文件,但会使其成为用户必须使用 map 拷贝的地方。

关于c++ - 使用临时对象将迭代器获取到 STL 容器时出现细微错误 : how to avoid it?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9806094/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com