【问题标题】:Get location of element you just pushed into vector C++获取刚刚推入矢量 C++ 的元素的位置
【发布时间】:2012-05-30 22:37:45
【问题描述】:

我很好奇推回向量是如何工作的。我想要一种方法来推回一个元素,然后能够将它在向量中的位置添加到用作地图类型的双精度数组中。

类似这样的:

// Create a bomb
Bomb b;
b.currentTime = SDL_GetTicks();
b.explodeTime = SDL_GetTicks() + 3000;
b.owner = player;
b.power = 2;    
b.x = x;
b.y = y;

bombVec.push_back(b);

bombs[y][x] = THIS_IS_WHAT_I_WANT;

这样当我引爆炸弹时,我可以查看地图然后在向量中有一个ID来处理。每个非炸弹方块都会有一个-1。另外,只是好奇。想象一下,我在一个向量中有 3 个元素。我删除第二个,然后添加另一个。新元素是否与删除的元素位于同一位置?

谢谢!

【问题讨论】:

  • 从向量中删除不是一个好主意。它需要移动所有元素。不,它不会被插入到另一个被删除的地方,但总是在数组的末尾。你可能想看看list
  • @StevenBurnap,这是最后一个元素的迭代器,而不是最后一个元素本身。 *bombVec.rbegin()bombVec.back() 将是最后一个元素。使用它的索引是bombVec[bombVec.size()-1]
  • 当然你可以从向量中删除……这没有什么问题。如果您永远无法从中删除任何内容,那将是一种非常无用的数据类型!现在,如果您正在研究一种需要非常高效的算法,那么对向量进行大量添加/删除调用是一个坏主意……因为是的,删除需要移动其他元素。但是从向量中删除对象绝对没有错。
  • 一个similar question有更多答案

标签: c++ vector


【解决方案1】:

push_back之后,可以使用back获取元素。

Bomb b;
...
bombVec.push_back(b);
Bomb &bref = bombVec.back();

或者你想要索引?

强制警告:如果你推入另一个项目,并且容量不够大,向量将被调整大小。如果访问引用,这将使引用无效并导致程序错误。这不是问题 (1) 通过索引访问 (2) 如果指针存储在 vector (3) 如果您使用 list 而不是 (4) 如果您不调整 vector 的大小。

获取索引:

size_t index = bombVec.size();
bombVec.push_back(b);

【讨论】:

  • 我需要索引。谢谢!是的,我将确保永远不会调整矢量的大小。如果我保留 15 个元素,虽然创建了超过 15 个元素但一次不超过 10 个,这是否仍会阻止调整大小?
  • 是的,这将阻止调整大小。
  • 谢谢迪特里希。很有帮助。
  • 强制性警告(扩展):如果元素是向量中的erased 并且基本上每当操作修改时,引用也可能变为无效容器。
  • @DavidRodríguez-dribeas 索引呢?
【解决方案2】:

让我们从头开始:

另外,只是好奇。想象一下,我在一个向量中有 3 个元素。我删除第二个,然后添加另一个。新元素是否与被删除的元素位于同一位置?

Delete 在语言中具有精确的含义,在这种情况下没有意义,所以我假设您的意思是 erase 从容器中。当您从向量中擦除 一个元素时,所有索引大于被擦除元素的元素都会被移动(或复制)以填充被擦除元素留下的空白空间。如果您push_back 一个新元素,该元素将被添加到容器的 back 中,因此它不会占用相同的位置。

另一个选项不是擦除原始元素,而是将新元素写入旧元素所在的位置:v[ idx ] = new_value;。这将我们带到问题的第一部分:

我想要一种方法来推回一个元素,然后能够将它在向量中的位置添加到用作地图类型的双精度数组中

使用向量作为底层容器的问题是容器上的任何变异操作都会使迭代器和对存储元素的引用无效。例如,上面的erase 将使迭代器和指向具有更大索引的所有元素的指针无效(从技术上讲,它根据标准使 all 迭代器无效,但实际上......)。向容器中添加元素可能会更糟,因为如果向量需要增长,它实际上会使 所有 迭代器/引用无效。

一个常见的建议替代方法是保留元素位置的索引。虽然如果容器增长,索引是稳定的,但如果您从容器中擦除,它们将引用错误的位置,因此您需要小心操作方式。如果您可以设法不从向量中移除元素(例如添加一个标记,将炸弹标记为已移除但实际上并未将其从容器中移除),那么问题就会变得简单得多。

【讨论】:

    猜你喜欢
    • 2017-01-04
    • 1970-01-01
    • 2018-05-14
    • 1970-01-01
    • 2011-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-23
    相关资源
    最近更新 更多