تعزيز الحاوية متعددة الفهارس بفهرس يعتمد على القيم المتداخلة

StackOverflow https://stackoverflow.com/questions/1628321

  •  06-07-2019
  •  | 
  •  

سؤال

إذا كان لدي كائن مثل هذا:

struct Bar {
    std::string const& property();
};

يمكنني إنشاء حاوية متعددة الفهارس لها مثل هذا:

struct tag_prop {};
typedef boost::multi_index_container<
    Bar,
    boost::multi_index::indexed_by<
        boost::multi_index::ordered_non_unique<
            boost::multi_index::tag<tag_prop>,
            boost::multi_index::const_mem_fun<
                Bar, const std::string&, &Bar::property
            >
        >
    >
    , ... other indexes
> BarContainer;

ولكن إذا كان لدي فصل مثل هذا:

struct Foo {
   Bar const& bar();
};

كيف يمكنني إنشاء فهرس على .bar().property() لحاوية من Foo أشياء؟

عادةً ما أقوم بتداخل المكالمات إلى boost::bind, ، لكن لا يمكنني معرفة كيفية جعلها تعمل في سياق حاوية متعددة الفهارس.

هل كانت مفيدة؟

المحلول

أعتقد أنك بحاجة إلى إنشاء كائن أصلي يأخذ مثيلين من 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 مرجع للمؤشرات المرتبة

نصائح أخرى

وبدلا من توفير للمقارنة المعرفة من قبل المستخدم، ويمكن أن تكتب المعرفة <م> مستخرج الرئيسي :

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

وبقدر ما أحب استخدام lambdas أن تفعل أشياء بسيطة، وهذا يمكن أن تتحول بسرعة:)

في قضيتك، لأنه قليلا أكثر تعقيدا، وأود أن تعتمد إما على وظيفة خالية أو للمقارنة المسند.

ووالمسند لديه ميزة تحديد أنواع أكثر وضوحا بحيث انها عادة ما تكون أسهل للوصول بها فعلا في.

وأيضا، من أجل سهولة القراءة، وأنا عادة 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;

وهذا النهج المسند يتطلب رمز أكثر النمطي، لكنه يسمح لفصل لطيف منطق المقارنة من تعريف المؤشر الذي هو في حد ذاته فصلها عن تعريف الحاوية.

وفصل واضح يجعل من الاسهل لعرض هيكل في لمحة.

scroll top