Boost Multi_Index 问题

发布于 2024-09-15 02:03:46 字数 1269 浏览 10 评论 0原文

抱歉,我无法在标题中说得更具体。

假设我有一个 Foo 类

class Foo {
public:
    Foo() { m_bitset.reset(); }

    void set_i(int i) {
        m_bitset.set(1);
        m_i = i;
    }

    void set_j(int j) {
        m_bitset.set(2);
        m_j = j;
    }
    bool i_set() { return m_bitset(1); }
    bool j_set() { return m_bitset(2); }
    void clear_i() { m_bitset.reset(1); }
    void clear_j() { m_bitset.reset(2); }
    int get_i() {
        assert(i_set());
        return m_i;
    }
    int get_j() {
        assert(j_set());
        return m_j;
    }

private:
    int m_i, m_j;
    bitset<2> m_bitset;
};

,现在我想将 Foo 放入 multi_index 中。

typedef multi_index_container <
    Foo, 
    indexed_by<
        ordered_non_unique<BOOST_MULTI_INDEX_CONST_MEM_FUN( Foo, int, get_i)
        >,
        ordered_non_unique<BOOST_MULTI_INDEX_CONST_MEM_FUN( Foo, int, get_j)
        >
    >
> Foo_set;

我试图找出一种方法,让我的 multi_index 对具有 i 或 j 有效值(或在 composite_key 的情况下两者都有)的 Foo 进行排序,并传递其余的。 所以我不希望下面的代码崩溃,我只想返回具有 i 有效值的 foos。

for (Foo_set::nth_index<1>::type::iterator it = foos.get<1>().begin(); it != foos.get<1>().end(); ++it)
    cout << *it;

Sorry I can't be more specific in the title.

Let's say I have a class Foo

class Foo {
public:
    Foo() { m_bitset.reset(); }

    void set_i(int i) {
        m_bitset.set(1);
        m_i = i;
    }

    void set_j(int j) {
        m_bitset.set(2);
        m_j = j;
    }
    bool i_set() { return m_bitset(1); }
    bool j_set() { return m_bitset(2); }
    void clear_i() { m_bitset.reset(1); }
    void clear_j() { m_bitset.reset(2); }
    int get_i() {
        assert(i_set());
        return m_i;
    }
    int get_j() {
        assert(j_set());
        return m_j;
    }

private:
    int m_i, m_j;
    bitset<2> m_bitset;
};

And now I want to put Foo's into a multi_index.

typedef multi_index_container <
    Foo, 
    indexed_by<
        ordered_non_unique<BOOST_MULTI_INDEX_CONST_MEM_FUN( Foo, int, get_i)
        >,
        ordered_non_unique<BOOST_MULTI_INDEX_CONST_MEM_FUN( Foo, int, get_j)
        >
    >
> Foo_set;

What I'm trying to figure out is a way to have my multi_index sort the Foo's that have valid values of i or j (or both in the case of a composite_key and pass over the rest.
So I don't want the code below to blow up, I just want to only return foos that have valid values for i.

for (Foo_set::nth_index<1>::type::iterator it = foos.get<1>().begin(); it != foos.get<1>().end(); ++it)
    cout << *it;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦在深巷 2024-09-22 02:03:46

通过浏览 boost multi_index 库文档,我想说这个库不可能实现你想要的。看看它的基本原理看起来它只是为了索引在所有“维度”上完全可索引的元素而设计的。 (您可以尝试在 boost 用户邮件列表上询问是否有任何允许“稀疏”索引维度的技巧。)

无论如何 - 根据问题的确切性质,您可能可以通过使用 boost::optional 来解决它作为索引类型。 (尽管我什至不确定是否可以通过 boost::Optional 进行索引。)

From skimming over the boost multi_index library docs I'd say what you want is not possible with this library. Looking at its rationale it appears that it is only made for indexing elements that are fully indexable over all "dimensions". (You might try asking on the boost users mailing list if there are any hacks to allow "sparse" index dimensions.)

Anyways - depending on the exact nature of your problem you might be able to work around it by using a boost::optional as indexing type. (Although I'm not even sure it's possible to index by boost::optional.)

叹梦 2024-09-22 02:03:46

get_i()get_j() 函数中使用 assert() 将导致当 multi_index 请求 i 时程序硬停止用于索引的j 值。

听起来您想要空对象模式行为。即 m_im_j 是采用特殊值来指示它们未设置的数据类型(如果它们是指针,则 NULL 指针将用作这个目的)。然后,您的多重索引可以对这些值进行索引,将所有 null 值集中在一起。

访问数据时,可以使用 boost:: range 过滤掉空值:

// Predicate for null testing
struct is_not_null {
    bool operator()(const Foo& f) { return f.get_i() != NULL && f.get_j() != NULL; }
};

Foo_set::nth_index<1>::type& idx = foos.get<1>();
BOOST_FOREACH(const Foo& f, idx | filtered(is_not_null())) {
    ;// do something with the non-null Foo's
}

如果您不想污染变量的值空间(即没有可以存储的有意义的空值),您还可以考虑转换您的 m_im_j 成员转换为 boost::可选's。通过更多的函子包装,您可以创建 的复合索引,这将允许您单独访问设置或取消设置 Foo。您可以进一步组合索引,将 ij 组合成一个类似于 的复合索引。

Having assert() in your get_i() and get_j() functions will cause a hard program stop when multi_index asks for the i or j values for indexing.

It sounds like you want Null Object Pattern behaviour. I.e. m_i and m_j are data-types that take special values to indicate they are not set (if they were pointers, the NULL pointer would serve this purpose). Then your multi-index could index on those values, lumping all the null values together.

When accessing the data, you can use boost::range to filter out the null values:

// Predicate for null testing
struct is_not_null {
    bool operator()(const Foo& f) { return f.get_i() != NULL && f.get_j() != NULL; }
};

Foo_set::nth_index<1>::type& idx = foos.get<1>();
BOOST_FOREACH(const Foo& f, idx | filtered(is_not_null())) {
    ;// do something with the non-null Foo's
}

If you don't want to pollute the value-space of your variables (i.e. there is no meaningful null value that can be stored), you could also look into converting your m_i and m_j members into boost::optional's. With a bit more functor wrapping, you could create a composite index of <bool, int>, which would allow you to access set or unset Foo's separately. You can further compose the index to combine i and j with a composite index that looks like <bool, bool, int, int>.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文