Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/133.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何在std::map中添加元素自己做分配?_C++_Dictionary - Fatal编程技术网

C++ 如何在std::map中添加元素自己做分配?

C++ 如何在std::map中添加元素自己做分配?,c++,dictionary,C++,Dictionary,我的问题背后的目的是使用std::map(即插入、删除、访问),并保证std::map实现不会引发异常 删除不是问题,如果仔细使用,访问也不是问题(例如,没有检查就没有at) 但插入是另一个问题。在此代码中: #include <map> struct foo{}; int main() { std::map<int, foo> my_map; my_map.insert(std::pair<int, foo>(42, foo{})); } 但

我的问题背后的目的是使用
std::map
(即插入、删除、访问),并保证
std::map
实现不会引发异常

删除不是问题,如果仔细使用,访问也不是问题(例如,没有检查就没有
at

但插入是另一个问题。在此代码中:

#include <map>

struct foo{};

int main()
{
  std::map<int, foo> my_map;

  my_map.insert(std::pair<int, foo>(42, foo{}));
}
但是,插入的
并没有这种过载


你们有解决方案吗?

使用节点提取和转换:

{
    std::map<int, foo> staging_map;
    staging_map.emplace(42, foo{});

    real_map.insert(staging_map.extract(42));  // cannot throw
}

使用节点提取和平移:

{
    std::map<int, foo> staging_map;
    staging_map.emplace(42, foo{});

    real_map.insert(staging_map.extract(42));  // cannot throw
}
我的问题的目的是使用std::map(即插入), 删除,访问)并保证不会从 映射实现

如果在实例化

标准::地图

那么你不能做出任何例外保证。在
中插入
放置

: 除非另有规定,本条款中定义的所有容器 使用分配器获取内存


我看不出在大多数STL实现中,在没有内存分配的情况下进行插入是如何可能的,因为可以利用堆分配的节点。您可能希望使用一个自定义分配器,该分配器从现有内存池进行分配,且无异常保证。或者编写自己的容器

我的问题的目的是使用std::map(即插入), 删除,访问)并保证不会从 映射实现

如果在实例化

标准::地图

那么你不能做出任何例外保证。在
中插入
放置

: 除非另有规定,本条款中定义的所有容器 使用分配器获取内存



我看不出在大多数STL实现中,在没有内存分配的情况下进行插入是如何可能的,因为可以利用堆分配的节点。您可能希望使用一个自定义分配器,该分配器从现有内存池进行分配,且无异常保证。或者编写自己的容器。

为映射指定一个自定义分配器。然后,您可以使该分配器成为非异常的;)。但是,如果内存不足,您必须计算出希望发生什么。请为映射指定一个自定义分配器。然后,您可以使该分配器成为非异常的;)。但是,如果内存不足,您必须计算出您希望发生的事情。请注意,它来自C++17。不能
staging\u map.emplace(42,foo{})仍然抛出异常?@NathanOliver是的,所以我认为这并不能解决问题。@NathanOliver:是的,当然,总有一些部分你分配了一些东西,但可能会失败。结果是,我们可以用这样的方法任意地将该点移动到远离最终插入的地方。好的。我只是想看看。当我们可以实际移动节点时,这将非常好。注意,它来自C++17。不能
staging_-map.emplace(42,foo{})仍然抛出异常?@NathanOliver是的,所以我认为这并不能解决问题。@NathanOliver:是的,当然,总有一些部分你分配了一些东西,但可能会失败。结果是,我们可以用这样的方法任意地将该点移动到远离最终插入的地方。好的。我只是想看看。如果我们真的可以移动节点,那就太好了。你的答案似乎最符合我的需要。在自定义分配器中,我测试
new
的返回,如果
nullptr
,则中止程序。您的答案似乎最符合我的需要。在自定义分配器中,我测试
new
的返回,如果
nullptr
,则中止程序。
auto nh = staging_map.extract(42);
// Done initializing.

// use nh freely

real_map.insert(std::move(nh));  // guaranteed to work