Возможно ли создание C ++ bimap, если одна сторона представления имеет другой ключ, чем другая сторона значения представления?Как это сделать? - PullRequest
0 голосов
/ 04 июня 2018

Сначала мне нужна была карта, поэтому я использовал std :: map.
Затем были добавлены некоторые требования, и мне нужно было также получить «ключи» для «значения» (foos для bar), поэтому я использовал

boost::bimaps::bimap<
  boost::bimaps::unordered_set_of<boost::bimaps::tagged<std::string, foo>>, 
  boost::bimaps::multiset_of<boost::bimaps::tagged<std::string, bar>>>

И после этого были добавлены еще некоторые требования,так что теперь мне нужно хранить номер для каждого foo, и с правой стороны мне нужно иметь возможность звонить <bimap>.righ.find(bar) и получать пары (foo + номер, сохраненный для foo), но я все еще хочу иметь возможность звонить <bimap>.left.find(foo) и получите бар.

Как этого добиться?Я бы предпочел какой-нибудь современный C ++, чем буст, если это возможно, но я думаю, что сложнее иметь функциональность bimap без буста.

РЕДАКТИРОВАТЬ: я должен отметить, что размер имеет значение, поэтому я не хочу хранить какую-либо часть, вовлеченную дважды, и скорость также имеет значение.

У меня должно быть что-то вроде
"foo1"+100 <-> "bar1" и "foo2"+300 <-> "bar4".
, и я хочу иметь возможность позвонить <bimap>.left.find("foo1") и получить "bar1",
, но также <bimap>.right.find("bar1")и получить пару ("foo1", 100).

1 Ответ

0 голосов
/ 05 июня 2018
#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
...