6

如果我有这样的对象:

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,但我不知道如何使它在多索引容器的上下文中工作。

4

3 回答 3

6

您可以编写一个用户定义的密钥提取器,而不是提供用户定义的比较器:

结构 FooBarPropertyExtractor
{
  typedef std::string result_type;
  const result_type& oeprator()(const Foo& f)
  {
    返回 f.bar().property();
  }
};

...

typedef boost::multi_index_container<
        酒吧,
        boost::multi_index::indexed_by<
                boost::multi_index::ordered_non_unique<
                        boost::multi_index::tag<tag_prop>,
                        FooBarPropertyExtractor
                >
        >
        , ... 其他索引
> FooContainer;

请参阅Boost.MultiIndex 键提取器的高级功能

于 2009-11-02T12:50:53.770 回答
5

我相信您需要创建一个谓词对象,该对象需要两个 Foo 实例,并且它的 operator() 可以在两个实例上调用 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 有序索引参考

于 2009-10-27T02:07:55.520 回答
1

尽管我喜欢使用 lambda 来做简单的事情,但这会很快退化:)

在您的情况下,由于它有点复杂,我将依赖自由函数或谓词比较器。

谓词具有更清楚地定义类型的优点,因此通常更容易实际引入它。

另外,为了便于阅读,我通常会键入我的索引,它给出:

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;

谓词方法需要更多样板代码,但它允许将比较逻辑与索引定义很好地分开,索引定义本身与容器定义分开。

清晰的分隔使结构更容易一目了然。

于 2009-10-27T09:09:37.170 回答