- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在考虑编写一些代码,归结为这一点。 T
是一个集合类型(当前是 std::map
,如果重要的话)。
T coll;
// ...
T::iterator it, prev;
prev = coll.end();
for(it = coll.begin(); it != coll.end(); ++it) {
if(prev != coll.end())
{ do something involving previous element; }
do something involving this element;
prev = it;
}
我的问题是,像这样将 it
复制到 prev
是不是一个坏主意?画风不好?可能会惹恼某个地方的学究?是否可能根据 T
类型的细微细节而中断?
我不希望 coll
在这个循环运行时被破坏,或者任何元素被添加到其中或从中删除。
一方面,我所知道的关于迭代器的一切都表明这应该是完全安全的。但另一方面,关于迭代器,有些事情我不了解,这感觉有点粗略,所以我想问一下。
附录:
出现这种情况的另一个原因是我的实际代码不会涉及我在上面编写的 for
循环。我实际拥有的是事件驱动代码;看起来更像这样:
void onStartDoingSomething() {
it = coll.start();
prev = coll.end();
startOperation(it, prev);
timerStart();
}
void onTimer() {
if(finished with operation on it) {
prev = it;
++it;
startOperation(it, prev);
if(it == coll.end() {
timerStop();
call operation finished;
}
}
}
void startOperation(T::iterator next, T::iterator prev) {
if(prev != coll.end()) {
finish operation on prev;
}
if(next != coll.end()) {
start operation on next;
}
}
因此,另一种陈述我的问题的方式可能是,“您是否必须仅在严格的传统 for
循环,还是可以任意使用它们?for
循环中是否保留了任何状态,或者状态是否全部在迭代器中?现在,我知道没有什么比“状态存储在 for
循环中”更重要的了,据我所知,迭代器包含它需要的所有状态是最重要的。因此,如果实际上迭代器不仅包含它需要的所有状态,而且还是 100% 安全可复制的,那么我最初问题的答案是“不,这不是一个坏主意”。但潜在的可能性是迭代器可能无法 100% 安全地复制——例如,如果在复制迭代器时出现细微的别名问题,递增原始迭代器,然后尝试使用拷贝——这就是为什么这段代码感觉如此-对我来说有点粗略。
最佳答案
这取决于迭代器的类型,但它适用于 std::map::iterator
。
迭代器分为不同的类别,这取决于它们支持的操作以及它们提供的关于它们引用的值的保证。
std::map::iterator
满足 BidirectionalIterator
的要求概念。这意味着,除其他事项外,递增迭代器的拷贝不会使原始拷贝无效。这意味着做 prev = it;++it
不会使 prev
无效,因此您的算法定义明确。
然而,并非所有迭代器都是这种情况。 InputIterator
概念不提供这种保证。注意 ++i
的后置条件:
Postcondition: Any copies of the previous value of
i
are no longer required to be either dereferenceable or to be in the domain of==
.
我不知道标准库中的任何迭代器会在您递增它们的拷贝时失去它们的值(value),但我个人已经构建了这样一个迭代器类型(它迭代存档文件中的条目,并且当您前进到下一个条目时,上一个条目将不再可读。
另见 Iterator
, ForwardIterator
, RandomAccessIterator
, 和 OutputIterator
概念。它们相互依存。
关于c++ - 制作迭代器的拷贝是个坏主意吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50159571/
我有一个基类和两个派生类,我需要将一个指向派生类对象的指针复制到另一个类中,就像示例一样。 class Base { public: Base(const Base& other); } cl
考虑 Container 类,它主要存储 Box 对象的 unique_ptr vector ,并可以对它们执行一些计算。 class Container { private: std::
引用是指保存的值为对象的地址。在 Python 语言中,一个变量保存的值除了基本类型保存的是值外,其它都是引用,因此对于它们的使用就需要小心一些。下面举个例子: 问题描述:已知一个列表,求生成一个
我正在尝试实现 Bron-Kerbosch 算法,这是一种用于查找派系的递归算法。我设法达到了一个点,它返回了正确数量的派系,但是当我打印它们时,它们不正确 - 添加了额外的节点。我在这里遗漏了什么明
在评估中,我选择了选项LINE I 上的运行时错误。没有未定义行为这样的选项,尽管我认为这是正确的选择。 我不确定,但我认为评估有误。我编译并运行了该程序,它确实打印了 3, 9, 0, 2, 1,
在函数签名中通过 const 值传递参数是否有任何好处(或相反,成本)? 所以: void foo( size_t nValue ) { // ... 对比 void foo( const s
我为 answer to another question 写了一个 OutputIterator .在这里: #include using namespace std; template clas
我有一个由第三方生成的 dll,它具有某种内部数据结构,将其大小限制为 X 个元素。 所以基本上,它有一个以 X 为限制的队列。 据我所知,DLL 是每个进程的,但是是否可以多次加载 DLL?也许每个
假设我有以下两个数据结构: std::vector all_items; std::set bad_items; all_items vector 包含所有已知项和 bad_items vector
如何在不渲染 CGImage 的情况下从另一个 CIImage 复制一个 CIImage 最佳答案 CIImage *copiedImage = [originalImage copy]; 正如您在
我有一个名为 UINode 的 GUI,我想创建一个拷贝并只更改一些内容。该项目由 3 个基本线程组成。 PingThread、RosThread 和 GuiThread。我试图复制粘贴项目文件夹并将
Qt 新手。如果这个问题太幼稚,请多多包涵。在 Windows 操作系统环境中,我有 Qt 对话框框架应用程序,它具有“重复”- 按钮。在同一目录中,有 Qt 应用程序 - (一个带有关闭按钮的对话框
我正在尝试创建一个函数来复制我的卡片结构。我只需复制 cvalue 即可轻松开始。然而,我的 cvalue 没有复制,当应该读取 1000 时它仍然读取 5。 #include #include
string str1("someString"); string str2 = string(str1);//how many copies are made here //copy2 =
我希望了解 boost::bind 执行何种函数对象的内部拷贝。由于这些对象的构造函数似乎没有被调用,我推测这是一种“非常浅的复制”,所以我引入了动态内存分配来产生一些错误。但是,下面代码的运行时输出
我正在查看 http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#c22-make-default-operations-consis
下面的类方法Augmented3dPoint::getWorldPoint()返回对其成员的引用 cv::Point3f world_point; class Augmented3dPoint { p
我需要通过 MyClass2 将用户定义的 lambda 传递给 MyClass1。我想确保只有一步,没有拷贝。下面的代码实现了吗?有没有更好的方法来做到这一点(比如使用编译器完成的隐式移动)? 注意
在我的数据库访问代码中,我想写一个方法: variant_t GetQueryRows (...) 我想这样调用它: const variant_t result = GetQueryRows (..
我有一个包含引用的类,例如: class A { A(B &b) : b(b) {} // constructor B &b; } 有时b必须是只读的,有时是可写的。当我创建一个 const A
我是一名优秀的程序员,十分优秀!