假设我有以下内容:
struct MetadataThingy {
void *actual_thingy;
int some_metadata;
int more_metadata;
bool operator<(MetadataThingy const& other) const {
return actual_thingy < other.actual_thingy;
}
};
where actual_thingy
指向一些重要的数据,我希望容器按值排序actual_thingy
而不是指向的元素的值,但我需要存储有关它的一些其他数据,所以我创建了包装类MetadataThingy
与一个比较器,只考虑的值actual_thingy
指针(而不是使用容器void *
)
现在,给出以下代码:
std::set<MetadataThingy> thingy_set;
void test() {
MetadataThingy m1 { nullptr, 5, 20 };
MetadataThingy m2 { &m1, 1, 2 };
MetadataThingy m3 { &m2, 6, 0 };
thingy_set.insert(m1);
thingy_set.insert(m2);
thingy_set.insert(m3);
MetadataThingy m;
m = *thingy_set.find(m2); // OK.
m = *thingy_set.find(static_cast<void *>(&m2)); // Nope. Can't use a pointer.
}
由于每个MetadataThingy
可以通过它存储的指针值唯一标识并按指针值排序,只需使用void *
作为钥匙。但就目前情况而言,我必须创建一个虚拟对象MetadataThingy
每次我搜索一个元素,都感觉很混乱。我已经考虑过只使用map
以指针为键并且MetadataThingy
作为价值,但因为每个MetadataThingy
无论如何还必须包含指针,这感觉有点多余。所以,考虑到两种类型的元素是相互可比的,有没有办法使用集合中存储的类型以外的元素来查找或删除集合中的值并且一种类型的元素可以唯一地映射到另一种类型(void *
and MetadataThingy
是同构的)? (我没有在上面的代码中包含任何内容,但假设有用于比较的运算符重载void *
and MetadataThingy
以任何顺序。)
关于我试图解决的问题的一些背景知识,以防万一有人可以推荐更好的方法:我需要按多个标准订购集合,所以我有几个MetadataThingy
容器,全部按不同标准排序。在这种情况下,“元数据”将是我需要跟踪所有容器中元素的位置的内容,以便我可以快速删除。这听起来像是增强多索引容器的完美工作,但这些元素的顺序不断变化,据我所知这意味着它不起作用。
从 C++14 开始,std::set
具有查找函数的模板化版本find
, lower_bound
等等。它们允许您传递任何对象进行比较,只要比较器支持即可。
这意味着您可以直接通过void*
to find
,只要比较器支持比较MetadataThingy
and void*
.
有关更多信息,请参阅http://en.cppreference.com/w/cpp/container/set/find.
了解有关限制Compare::is_transparent
, 我发现这个 StackOverflow 问题很有帮助。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)