从std::vector中查找std::map中的对象
finding objects in std::map from std::vector
给各位c++专家一个快速的问题:
在我正在做的项目中,有一个类包含指向vector对象的指针:
std::vector<object*> objects;
并且有一个结构体可以为对象添加偏移量(Point2D显然是x,y坐标)
struct DraggedObject{
object* obj;
Point2D offset;
DraggedObject():obj(NULL),offset(Point2D(0,0)){}
};
当你拖动一个对象时它会将它添加到std::map中,就像这样:
std::map <int, DraggedObject> dragged_objects;
所以我的问题是:有一个循环,我需要移动这个对象,但跳过拖动的对象。我的问题是:是否有一种方法可以循环遍历对象向量并找出对象是否在dragged_object映射上?
我正在做这样的事情:
for(std::vector<object*>::iterator it = objects.begin(); it != objects.end(); it++){
if(//Object is not in dragged_objects){
(*it)->move_to( Point2D( //Some point);
}else{
(*it)->move_to (Point2D (//Point of dragged object);
}
但是我不知道如何做这个比较…
std::map优化为按键(在本例中为int值)快速查找,而不是按值(您的对象*)快速查找。所以你唯一的办法就是迭代整个地图,直到找到它。当映射很小且代码段对性能不重要时,可以这样做。当性能问题时,您可以添加一个额外的std::set并存储当前正在被拖动的所有对象,或者您可以让对象本身知道它们是否正在被拖动,并在您的对象类中添加一个isDragged()方法。
我相信您可以使用set_difference。你将不得不实现自定义比较器,而且你将不得不对向量中的元素排序。除非您这样做,否则我认为您只能对vector中的每个元素执行查找,以验证它是否存在于映射中。
如果可能的话,用object*
键收集容器(map
)中的拖动对象,例如std::map <object*, DraggedObject>
而不是std::map <int, DraggedObject>
。然后你可以这样写你的if
:
if(dragged_objects.count(*it)){
(*it)->move_to( Point2D( //Some point);
}else{
(*it)->move_to (Point2D (//Point of dragged object);
您可以改变您的方法并迭代您的拖动对象映射,在每个拖动对象上完成您需要完成的工作,然后将对象添加到临时std::vector<object*>
。当循环结束时,你可以遍历vector,只对不在临时vector中的元素做一些操作。
您可以使用的一种方法是将vector替换为一个列表,并使该列表仅包含未封装的对象。
然后遍历该列表。如果需要所有对象,则需要遍历illist和map。不确定这样做的顺序有多重要,但如果对象的id很重要(您存储在map中),您可以根据map中的id在列表和map中迭代"合并"。
在这种情况下,列表比向量更好的原因是,如果你要从集合的中间拖动对象,从列表中删除是常数时间。
既然您说对象ID是它们在dragged_objects
map中的键,那么您可以使用find
map方法。我认为应该是这样的。
std::map::iterator miter;
for (auto &obj : objects)
{
miter = dragged_objects.find(obj.id);
if (miter != dragged_objects.end()) {
/* do for non-dragged objects */
} else {
/* do for dragged objects */
}
}
根据需要调整非c++ 11编译器
用于索引的int
从何而来地图吗?如果它是从object
中提取的标识符,那么所有你要做的就是在循环中提取它,看看它是不是显示在地图上(使用map::find
)。否则,你会要么需要一个额外的映射,用object*索引,要么需要遍历所有的dragged_objects
,看看看看它是否有你想要的地址(std::find_if
)。根据dragged_objects
的数量,这可能是缓慢;但通常情况下,我猜dragged_objects
是两者之一为空或只有一个条目。如果是这样的话,每次循环的线性搜索都是完美的可以接受的。
- 将对象移动到std::shared_ptr
- 使用std::函数映射对象方法
- 使用"std::unordereded_map"映射到"std::list"对象
- 在c++中尝试对对象数组进行排序时,出现std:bad_alloc错误
- 当使用透明的std函数对象时,我们还需要写空的尖括号吗
- 如何使用std::min和std::less返回对象
- 如何将二进制格式的 C++ 对象的 std::vector 保存到磁盘?
- C++11 中不同类型的对象的 std::array 的替代方案
- 返回一个带有 std::move 的对象并链接函数
- std::vector::p ush_back() 不会在 MSVC 上编译具有已删除移动构造函数的对象
- 当指向对象的指针作为参数传递给 std::thread 时,内存可见性
- std::string 的对象真的可以移动吗?
- std::unordered_map 类型对象声明期间出现"field has incomplete type"错误
- 即发即弃 std::线程对象清理自身
- 当 std::move 与 C 样式数组或不移动对象时会发生什么
- 传递 std::vector of std::shared_ptr,而不是更新对象
- std::对象映射或对象指针
- 来自std ::对象向量的基础数据
- 在std::对象列表中快速搜索和删除
- 在不同 DLL 之间传递的 std 对象