huf*_*uff 63 c++ iterator stl dereference
有没有办法检查迭代器(无论是来自向量,列表,双端队列......)是否(仍)可解除引用,即未被无效?
我一直在使用try- catch,但是有更直接的方法吗?
示例:(不起作用)
list<int> l;
for (i = 1; i<10; i++) {
l.push_back(i * 10);
}
itd = l.begin();
itd++;
if (something) {
l.erase(itd);
}
/* now, in other place.. check if itd points to somewhere meaningful */
if (itd != l.end())
{
// blablabla
}
Run Code Online (Sandbox Code Playgroud)
小智 61
我假设你的意思是"迭代器是有效的",它由于容器的更改而没有失效(例如,插入/擦除向量).在这种情况下,不,您无法确定迭代器是否(安全地)可解除引用.
ava*_*kar 25
正如jdehaan所说,如果迭代器没有失效并指向容器,你可以通过比较来检查container.end().
但请注意,如果迭代器是单数的 - 因为它没有被初始化,或者在容器上的变异操作之后变得无效(例如,当你增加向量的容量时,向量的迭代器无效) - 唯一的操作是你被允许执行就是任务.换句话说,您无法检查迭代器是否是单数.
std::vector<int>::iterator iter = vec.begin();
vec.resize(vec.capacity() + 1);
// iter is now singular, you may only perform assignment on it,
// there is no way in general to determine whether it is singular or not
Run Code Online (Sandbox Code Playgroud)
Ter*_*fey 10
不可移植的答案:是的 - 在Visual Studio中
Visual Studio的STL迭代器具有"调试"模式,正是这样做的.您不希望在发布版本中启用此功能(存在开销),但在已检查的版本中非常有用.
阅读关于它的VC10 这里(该系统能在事实上的确改变了每一个版本,所以查找特定于您的版本的文档).
编辑此外,我应该补充:Visual Studio中的调试迭代器被设计为在您使用它们时立即爆炸(而不是未定义的行为); 不允许"查询"他们的国家.
通常你通过检查它是否与end()不同来测试它
if (it != container.end())
{
// then dereference
}
Run Code Online (Sandbox Code Playgroud)
此外,在设计和性能方面使用异常处理来替换逻辑是不好的.您的问题非常好,在您的代码中绝对值得替换.名称之类的异常处理仅用于罕见的意外问题.
有没有办法检查迭代器(无论是来自向量,列表,双端队列......)是否(仍)可解除引用,即尚未失效?
不,没有.相反,您需要在迭代器存在时控制对容器的访问,例如:
当你的线程仍在使用该容器的实例化迭代器时,你的线程不应该修改容器(使迭代器无效)
如果在线程迭代时存在其他线程可能修改容器的风险,那么为了使这个场景成为线程安全的,您的线程必须在容器上获得某种锁定(这样它就可以防止其他线程修改容器它正在使用迭代器)
像捕获异常这样的解决方法是行不通的.
这是一个更普遍的问题的特定实例,"我可以测试/检测指针是否有效吗?",答案通常是"不,你不能测试它:相反,你必须管理所有的内存分配和删除,以便知道任何给定的指针是否仍然有效".
| 归档时间: |
|
| 查看次数: |
66140 次 |
| 最近记录: |