Мультииндексный контейнер повышения с индексом на основе вложенных значений

Задержанное выполнение

6
задан Tim Sylvester 27 October 2009 в 01:42
поделиться

3 ответа

Я считаю, что вам нужно создать объект предиката, который принимает два экземпляра Foo, и его оператор () может вызывать Foo :: bar () в обоих экземплярах.

Что-то вроде

struct MyPredicate
{

    bool operator() (const Foo& obj1, const Foo& obj2) const
    {
        // fill in here
    }
};

, а затем используйте

...
boost::multi_index::ordered_unique<boost::multi_index::tag<tag_prop>, 
    boost::multi_index::identity<Foo>, MyPredicate>,
...

Ознакомьтесь с Ссылка на упорядоченные индексы MultiIndex

5
ответ дан 9 December 2019 в 20:45
поделиться

Вместо предоставления определяемого пользователем компаратора вы можете написать определяемый пользователем экстрактор ключей :

struct FooBarPropertyExtractor
{
  typedef std::string result_type;
  const result_type& oeprator()(const Foo& f)
  {
    return f.bar().property();
  }
};

...

typedef boost::multi_index_container<
        Bar,
        boost::multi_index::indexed_by<
                boost::multi_index::ordered_non_unique<
                        boost::multi_index::tag<tag_prop>,
                        FooBarPropertyExtractor
                >
        >
        , ... other indexes
> FooContainer;

См. Расширенные функции экстракторов ключей Boost.MultiIndex

6
ответ дан 9 December 2019 в 20:45
поделиться

Как бы мне ни нравилось использовать лямбда-выражения для простых вещей, это может быстро ухудшиться :)

В вашем случае, поскольку это немного сложнее, я бы полагался либо на бесплатную функцию, либо на компаратор предикатов.

Предикат имеет преимущество в том, что он более четко определяет типы, поэтому его обычно легче ввести.

Кроме того, для удобства чтения я обычно typedef мои индексы, что дает:

namespace mi = boost::multi_index;

struct FooComparator
{
  bool operator()(Foo const& lhs, Foo const& rhs) const
  {
    return lhs.bar().property() < rhs.bar().property();
  }
};

typedef mi::ordered_unique <
          mi::tag<tag_prop>,
          mi::identity<Foo>,
          FooComparator
        > foo_bar_index_t;

typedef boost::multi_index_container <
          Foo,
          mi::indexed_by < 
            foo_bar_index_t,
            // ... other indexes
          >
        > foo_container_t;

Подход с предикатами требует большего количества шаблонного кода, но он позволяет четко отделить логику сравнения от определения индекса, которое само по себе отделено от определения контейнера.

Четкое разделение упрощает задачу для быстрого просмотра конструкции.

1
ответ дан 9 December 2019 в 20:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: