Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/146.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++ &引用;逆;关联容器?_C++_Stl_Std - Fatal编程技术网

C++ &引用;逆;关联容器?

C++ &引用;逆;关联容器?,c++,stl,std,C++,Stl,Std,stl中或一般情况下是否存在一种“反向”关联容器? 例如,我想要一个容器,其中相同的元素由一组键共享 假设我的密钥是一个int,那么我将拥有例如: container.at(3) -> some object A container.at(4) -> same object A container.at(1) -> other object B 对于不同的操作,这个容器(理想情况下)具有与std::map相同的复杂性。这可能吗 我开始考虑使用一个std::map,其中多个索引

stl中或一般情况下是否存在一种“反向”关联容器? 例如,我想要一个容器,其中相同的元素由一组键共享

假设我的密钥是一个
int
,那么我将拥有例如:

container.at(3) -> some object A
container.at(4) -> same object A
container.at(1) -> other object B
对于不同的操作,这个容器(理想情况下)具有与std::map相同的复杂性。这可能吗

我开始考虑使用一个
std::map
,其中多个索引指向同一个对象,但是当从映射中删除一个项目时,运行时间是以O(n)为单位的,因为您必须检查其他项目,以查看是否需要删除T
对象

stl或boost中是否已经存在这种“本机”容器

编辑: 使用的一些示例:

container<int, myClass> myContainer;
myClass obj(...); //new object
myContainer.insert(3, obj); //insert object for specific key
myContainer.insert(2, obj); //insert same object for specific key, since both objects would compare equal we would actually not "insert" a new object but have it shared by both keys
myContainer.duplicate_object(2,5); //key 5 also has the same object as key 2 (and 3)
myContainer.getAllKeys(2); //would return 2,3 and 5 since they all reference the same object as key 2
myContainer.removeKey(3);
myContainer.removeKey(2);
myContainer.removeKey(5); //would destroy the object here, not before
集装箱集装箱;
myClass obj(…)//新对象
myContainer.插入物(3,obj)//为特定键插入对象
myContainer.插入物(2,obj)//为特定键插入相同的对象,因为两个对象的比较相等,所以我们实际上不会“插入”一个新对象,而是让它由两个键共享
myContainer.replicate_对象(2,5)//键5也具有与键2(和3)相同的对象
myContainer.getallkey(2)//将返回2、3和5,因为它们都引用与键2相同的对象
myContainer.removeKey(3);
myContainer.removeKey(2);
myContainer.removeKey(5)//会破坏这里的物体,而不是之前
您可以使用

std::map<int,std::shared_ptr<myclass>>
std::map
在C++11中,这是标准的一部分。否则,请使用Boost库提供的共享指针

共享指针的概念是,它在内部保持引用计数,即它跟踪指针的复制次数。删除映射项时,共享指针对象的析构函数将确保计数器递减。一旦它达到零,对象将被删除


(编辑:)为使答案更完整,请提供几个用法示例:

#include <map>
#include <memory>

struct myclass
{

};


int main()
{
  std::map<int,std::shared_ptr<myclass>> mymap;

  /* std::make_shared() calls the constructor and creates a shared_ptr: */
  std::shared_ptr<myclass> object1 { std::make_shared<myclass>() };
  std::shared_ptr<myclass> object2 { std::make_shared<myclass>() };
  std::shared_ptr<myclass> object3 { std::make_shared<myclass>() };

  mymap[1] = object1;
  mymap[2] = object2;
  mymap[3] = object3;
  mymap[4] = object2;
  mymap[5] = object1;

  mymap.erase(2); // erases the (2,object2) entry
                  // therefore, decreases the counter
                  // for object2
                  // but (4,object2) is still intact

  return 0;
}
#包括
#包括
结构myclass
{
};
int main()
{
std::map mymap;
/*std::make_shared()调用构造函数并创建共享的_ptr:*/
std::shared_ptr object1{std::make_shared()};
std::shared_ptr object2{std::make_shared()};
std::shared_ptr object3{std::make_shared()};
mymap[1]=object1;
mymap[2]=object2;
mymap[3]=object3;
mymap[4]=object2;
mymap[5]=object1;
mymap.erase(2);//删除(2,object2)项
//因此,减少计数器
//对于object2
//但是(4,object2)仍然完好无损
返回0;
}

因此,您需要的是像std::map中一样快速插入和查找,以及按值快速删除条目的功能

没有标准的容器可以做到这一点。但当您想自己编写一个时,可以通过维护两个内部数据结构来实现:

  • 将键映射到值的方法
  • 将值映射到指向它们的键集的第二个键
  • 当您想按值删除键时,可以在第二个映射中查找它。

    您可能想查看;描述说:

    Boost多索引容器库提供了一个类模板 命名的多索引容器,用于构造 保持一个或多个具有不同排序和排序的索引的容器 访问语义


    我不明白这个问题。你的标题使用“反向”一词,你的问题使用“反向”一词。不管怎样,你的例子仍然没有阐明你的意思。你能举例说明你将如何使用这种容器吗?假设存在reverse_容器或reverse_容器,并编写一个main()方法来说明它是如何工作的。此外,某种计数器允许您在O(1)时间内仍然删除。每次添加对象时递增计数器,每次删除对象时递减计数器。当计数为零时,您可以将其删除。(当然,这可能意味着扩展或包装std::map。)@Code-Guru:关于拥有计数器:您仍然需要在某个位置存储一个容器,表明该指针由n个键使用,用于映射中的所有指针。所以我不明白当你必须减少给定指针的计数器时,它怎么可能是O(1)?关于
    std::map
    ?顺便说一句,boost等被推荐用于共享指针的容器。@RealzSlaw有趣;我没有使用
    ptr\u map
    的经验,但是如果有一些理由支持此建议,则可能需要发布单独的答案。无论如何,谢谢你的评论。你的答案之间的区别只是性能不同。好吧,这在功能上是等价的。标题让人觉得这是他想要的,但他给出的例子让人觉得他只是想把轻量级对象作为值。