C++ 对两个不同字段进行排序并确定其唯一性的容器

C++ 对两个不同字段进行排序并确定其唯一性的容器,c++,map,set,containers,C++,Map,Set,Containers,假设我定义了一个类型,例如 struct Item { Item(int i, float j) : x(i), y(j) {} int x; float y; }; 我想将它们保存在一个容器中,该容器按Item::y对它们进行排序,并确保每个条目都有一个唯一的Item::x。我需要能够添加项目并删除顶部项目(即y值最小的项目) 换句话说,可以做到这一点的东西: Container<Item> my_container; my_container.inser

假设我定义了一个类型,例如

struct Item
{
    Item(int i, float j) : x(i), y(j) {}
    int x;
    float y;
};
我想将它们保存在一个容器中,该容器按
Item::y
对它们进行排序,并确保每个条目都有一个唯一的
Item::x
。我需要能够添加项目并删除顶部项目(即
y
值最小的项目)

换句话说,可以做到这一点的东西:

Container<Item> my_container;
my_container.insert(Item(0, 3.2));
my_container.insert(Item(2, 1.1));
my_container.insert(Item(0, 0.2));
my_container.insert(Item(1, 0.6));
my_container.insert(Item(3, 0.6));
my_container.insert(Item(0, 6.1));

for (auto &i : my_container)
  std::cout << i.x << " " << i.y << std::endl;
起初,我使用带有比较函数的
std::set
,确保
item_1.y
,但这不允许在
item_1.y==item_2.y
item_1.x!=项目2.x

有什么建议吗?多谢各位

更新

我决定研究Boost多索引,因为我有可用的Boost。我几乎有了一个解决方案(使用Joaquin下面的答案):

这几乎就是我想要的。请注意,插入x=0的项不会用该索引替换容器中的上一项。另外,顺便问一下,移除并返回容器中顶部项目的最佳方法是什么。这样的东西够了吗:

Item pop(my_container_t &mc)
{
  my_container_t::nth_index<0>::type& container = mc.get<0>();
  auto item = *container.begin();
  container.erase(container.begin());
  return item;
}
项目pop(my_container_t&mc)
{
my_container\u t::n_index::type&container=mc.get();
auto item=*container.begin();
container.erase(container.begin());
退货项目;
}

您需要两个容器:一个确保
x
的唯一性,另一个在
y
上提供订购,然后
x

一个
boost
multi_index
容器可以同时完成这两项任务,但可能会有过大的杀伤力

使用
集合
无序集合
x
值,并丢弃已经存在的东西


拥有一组元素,按
y
然后
x
排序(
std::tie(y,x)您需要两个容器:一个确保
x
的唯一性,另一个提供
y
然后
x
的排序

一个
boost
multi_index
容器可以同时完成这两项任务,但可能会有过大的杀伤力

使用
集合
无序集合
x
值,并丢弃已经存在的东西


< <代码> > <代码> >由<代码> y>代码>然后>代码> x>代码>(<代码> STD::Ty(y,x)

与别人所说的相反,我不考虑使用BooS.MulkObjultOff杀人:这正是LIB设计的那种情况。

using namespace boost::multi_index;

typedef multi_index_container<
    Item,
    indexed_by<
        ordered_non_unique<member<Item,float,&Item::y> >,
        ordered_unique<member<Item,int,&Item::x> >
    >
> my_container_t;
使用名称空间boost::multi_索引;
typedef多索引容器<
项目,,
索引<
有序非唯一,
有序_唯一
>
>我的集装箱;

>P>与别人所说的相反,我不考虑使用BooS.MulkObjultOff杀人:这正是LIB设计的那种情况。

using namespace boost::multi_index;

typedef multi_index_container<
    Item,
    indexed_by<
        ordered_non_unique<member<Item,float,&Item::y> >,
        ordered_unique<member<Item,int,&Item::x> >
    >
> my_container_t;
使用名称空间boost::multi_索引;
typedef多索引容器<
项目,,
索引<
有序非唯一,
有序_唯一
>
>我的集装箱;

您的示例有6个输入和4个输出,这令人困惑。@MooingDuck只有4个输出,因为带有
x=0
的项被添加了三次。很像一个集合,最后两个项没有添加到容器中,因为带有
x=0
的项已经在容器中。为什么不插入
项(0,4.7)
overwrite
Item(0,3.2)
?@MarkRansom抱歉,这是一个错误,我已经编辑了这个问题。假设他使用自己的自定义容器,他不能只更改容器的insert函数的逻辑,从而确定是否添加该项(基于x的值)以及在容器中的位置吗(基于y的值)?您的示例有6个输入和4个输出,这令人困惑。@MooningDuck只有4个输出,因为带有
x=0
的项被添加了三次。很像一个集合,最后两个项没有添加到容器中,因为带有
x=0
的项已经在容器中。为什么不插入
项(0,4.7)
overwrite
Item(0,3.2)
?@MarkRansom抱歉,这是一个错误,我已经编辑了这个问题。假设他使用自己的自定义容器,他不能只更改容器的insert函数的逻辑,从而确定是否添加该项(基于x的值)以及在容器中的位置吗(基于y的值)?
Item pop(my_container_t &mc)
{
  my_container_t::nth_index<0>::type& container = mc.get<0>();
  auto item = *container.begin();
  container.erase(container.begin());
  return item;
}
using namespace boost::multi_index;

typedef multi_index_container<
    Item,
    indexed_by<
        ordered_non_unique<member<Item,float,&Item::y> >,
        ordered_unique<member<Item,int,&Item::x> >
    >
> my_container_t;