通过引用获取std :: map中的对象是否安全?

bal*_*lki 17 c++ reference map

我有这样的地图

map<int,object> objmap;
object& obj = objmap.find(num)->second;
object& obj2 = objmap[num];
Run Code Online (Sandbox Code Playgroud)

无论我在对象中做出什么样的改变都必须反映在地图上.类似的事情不能在矢量中完成,因为它在需要更多空间时改变对象的位置.在std :: map中执行它是否安全?这是可取的吗?第二个版本给出错误,因为我的对象没有空构造函数.如果我声明一个空构造函数什么都不做,这两行会以同样的方式工作吗?

CB *_*ley 23

只要有问题的对象没有从地图中删除,那么它是安全的.一旦插入到地图中,即使添加或删除了其他元素,也不会移动对象.

object& obj = objmap.find(num)->second;
Run Code Online (Sandbox Code Playgroud)

这是有潜在危险的,除非您确定num地图中实际存在具有键的元素.如果您不确定,可以使用insert返回a iterator和a 的重载bool来指示是否已插入新元素或者具有给定键的元素是否已存在于地图中.

例如

object& obj = objmap.insert( std::make_pair(num, object(arg1, arg2, argN)) ).first->second;
Run Code Online (Sandbox Code Playgroud)


ice*_*ime 12

只要元素未从地图中删除,这就是安全的.

但是,第二行不太安全:

object& obj = objmap.find(num)->second;
Run Code Online (Sandbox Code Playgroud)

如果num地图中没有带键的元素,find则返回objmap.end().在取消引用返回的迭代器之前,应该测试这种可能性:

const std::map<int, object>::iterator it = objmap.find(num);
if (it != objmap.end())
{
    object& obj = it->second;
    /* ... */
}
Run Code Online (Sandbox Code Playgroud)

现在,如果目标不是真正找到但真的要插入,那么调用operator[]是可能的(尽管,正如您已经注意到的,它需要值来提供无参数构造函数).但你必须明白,这是两个非常不同的东西:

  • find 发现:如果找不到密钥,则不插入任何内容并end返回迭代器
  • operator[] 始终返回对映射中值的引用:如果键不存在,则发生插入(对于默认构造值:因此构造函数要求)