Можно ли переопределить методы "find" и "erase" boost :: bimaps :: bimap.left?Как это сделать? - PullRequest
0 голосов
/ 05 июня 2018

У меня есть следующее:

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;

, и я хочу иметь возможность вызывать методы поиска и стирания следующим образом:
instance.left.find("foo") вместо instance.left.find({"foo",1}) и
instance.left.erase("foo") вместоиз instance.left.erase({"foo",1}).

Я просто хочу использовать только часть "foo" в "foo_and_number_helper" вместо обеих частей для методов поиска и удаления, вызываемых с левой стороны.Как этого добиться?Я пытался прочитать реализацию bimap, но мне все еще трудно это сделать.

Я уже задавал более широкий вопрос: Возможно ли создание C ++ bimap, если одна сторона обзора имеет другой ключ, чем другая сторонастоимость представления?Как это сделать? и из комментариев я должен переопределить operator <, но я даже не уверен в этом и достаточно ли этого.

Ответы [ 2 ]

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

Так что да, это не отвечает на мой вопрос, но я думаю, что достиг того, чтоЯ хотел.

0 голосов
/ 05 июня 2018

Я бы пошел с 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 представление, у вас будет любое количество представлений

...