提问人:Lukas Salich 提问时间:6/5/2018 更新时间:6/6/2018 访问量:754
是否可以覆盖 boost::bimaps::bimap.left 的“find”和“erase”方法?怎么做?
Is it possible to override "find" and "erase" methods of boost::bimaps::bimap.left? How to do it?
问:
我有以下几点:
struct foo_and_number_helper {
std::string foo;
uint64_t number;
};
struct foo_and_number {};
struct bar {};
using my_bimap = boost::bimaps::bimap<
boost::bimaps::unordered_set_of<boost::bimaps::tagged<foo_and_number_helper, foo_and_number>>,
boost::bimaps::multiset_of<boost::bimaps::tagged<std::string, bar>>
>;
my_bimap instance;
我希望能够调用这样的 find 和 erase 方法:
而不是 和
instead of .instance.left.find("foo")
instance.left.find({"foo",1})
instance.left.erase("foo")
instance.left.erase({"foo",1})
我只想只使用“foo_and_number_helper”的“foo”部分,而不是两个部分,用于从左侧调用的查找和擦除方法。如何实现?我试图阅读 bimap 实现,但我仍然很难做到。
我已经问了更广泛的问题:C++ 双映射是否可以在视图的一侧与视图值的另一侧具有不同的键?怎么做呢?从评论中我必须覆盖,但我什至不确定这一点以及是否足够。operator <
答:
1赞
Caleth
6/5/2018
#1
我会在这里使用 boost::multi_index_container
。boost::bimap
namespace bmi = boost::multi_index;
struct ElementType {
std::string foo;
std::string bar;
uint64_t number;
}
using my_bimap = boost::multi_index_container<
ElementType,
bmi::indexed_by<
bmi::unordered_unique<
bmi::tagged<struct Foo>,
bmi::member<ElementType, std::string, &ElementType::foo>
>,
bmi::ordered<
bmi::tagged<struct Bar>,
bmi::member<ElementType, std::string, &ElementType::bar>
>,
// and others like
bmi::sequenced<
bmi::tagged<struct InsertionOrder>
>
>
>;
然后你会像这样使用它
my_bimap instance;
instance.get<Foo>().find("foo");
instance.get<Bar>().erase("bar");
std::cout << instance.get<InsertionOrder>()[10].foo;
也就是说,您拥有的不是 和 视图,而是任意数量的视图left
right
评论
0赞
Lukas Salich
6/5/2018
谢谢你的回答!我已经花了将近一天的时间寻找如何做到这一点。而且我忘了提到它必须节省空间(它可能是,foo、bar 和数字只存储一次)并且速度快(将包含数百万个值)。我猜 foo、bar 和 number 周围的空间很小,而且速度快不了。我说得对吗?
1赞
Caleth
6/5/2018
我认为是 的特例,或者至少是可以实施的。忽略索引(我添加索引是为了说明您可以拥有任意数量的索引),我希望它们是相同的数据结构:一个由 4 个指针和一个(或等效元组)组成的节点,排列为两个(不同的)平衡树boost::bimap
boost::multi_index_container
sequenced
ElementType
0赞
Lukas Salich
6/5/2018
你向我展示了如何使用它,但它需要完全重写!:D这在语法上是完全不正确的。
0赞
Lukas Salich
6/6/2018
#2
于是我按照@Caleth的回答进行了调整:
#include <boost/multi_index/hashed_index.hpp>
#include <boost/bimap/bimap.hpp>
using namespace std;
struct ElementType {
string foo;
string bar;
uint64_t number;
};
using namespace boost::multi_index;
using my_bimap = multi_index_container<
ElementType,
indexed_by<
hashed_unique<member<ElementType, string, &ElementType::foo>>,
ordered_non_unique<member<ElementType, string, &ElementType::bar>>
>
>;
int main() {
my_bimap instance;
instance.insert({"foo", "bar", 0});
instance.insert({"bar", "bar", 1});
cout << instance.get<0>().find("bar")->foo << endl;
cout << instance.get<0>().find("bar")->bar << endl;
cout << instance.get<0>().find("bar")->number << endl;
auto range = instance.get<1>().equal_range("bar");
for (auto it = range.first; it != range.second; ++it) {
cout << it->foo << endl;
cout << it->number << endl;
}
cin.sync();
cin.ignore();
}
输出:
bar
bar
1
foo
0
bar
1
所以是的,它没有回答我的问题,但我认为我实现了我想要的。
评论