创建地图元素时避免使用值复制

时间:2014-11-13 14:43:52

标签: c++

我有一个std::map<std::string, std::vector<double>> foo,其内容使用函数

缓慢构建
bar(
    std::string key   /*key name*/,
    std::size_t index /*element index of the vector*/,
    double value      /*value to put in the vector at that index*/
)

这个函数以一种我信任的方式填充foo,从函数参数类型和那些简短的注释中可以看出。

但是,我担心当我添加一个新密钥时会发生这种情况

auto it = foo.find(index);
if (it == foo.end()){
   /*ToDo - avoid taking a vector value copy*/

我最终创建了一个新的std::vector<double>,并将其放入地图中。这导致我获取该向量的值副本。有没有一种方法(除了使用智能指针作为地图值)而不进行值复制?

2 个答案:

答案 0 :(得分:5)

自C ++ 11以来有一个很好的方法(考虑到你使用auto,你正在使用它)。此标准允许使用称为安置的特殊类型的插入。最简单的方法是使用

it = foo.emplace(
    std::make_pair(key, std::vector<double>(1 + index, 0.0/*a default value*/))
).first;

然后调用it->second.at(index) = value,如果find 返回元素,那么您可能会这样做。

安置技术正在利用匿名临时std::vector和匿名临时std::pair的移动构造函数。 (那些临时名称被称为 r值引用)。

有关详细信息,请参阅http://en.cppreference.com/w/cpp/container/map/emplace

答案 1 :(得分:4)

如果密钥存在,您可以使用std::map::operator[]获取对值的引用,或者如果密钥不存在,则创建一个新引用。

std::vector<double>& targetarray = foo[key];
// resize targetarray if required
targetarray[index] = value;