避开Boost Multi-Index容器的常量元素 [英] Getting around Boost Multi-Index container's constant elements

查看:56
本文介绍了避开Boost Multi-Index容器的常量元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些数据类,它的复制成本很高,但必须可变,因为它经常根据事件进行更新.我还需要一个多索引容器来容纳许多此类.我正在尝试使用boost :: multi_index进行设置.例如:

I have some data class which is expensive to copy, but must be mutable, as it is frequently updated according to events. I also need a multi-index container to hold many such classes. I'm trying to set it up using boost::multi_index. For example:

struct MutableAndExpensiveToCopy {
    int some_value;
    std::map<int, std::string> some_huge_map;
    std::map<int, std::string> an_even_bigger_map;
}

struct CanBeMultiIndexed
{
    // "Payload" - its fields will never be used as indices
    MutableAndExpensiveToCopy data;

    // Indexes        
    int         id;
    std::string label;
}

typedef multi_index_container<
    CanBeMultiIndexed,
    indexed_by<
        ordered_unique<member<CanBeMultiIndexed, int, &CanBeMultiIndexed::id>>,
        ordered_non_unique<member<CanBeMultiIndexed,std::string,&CanBeMultiIndexed::label>>
    > 
> MyDataContainer;

我的问题是multi_index将容器中的元素视为常量(以保持所有索引的完整性).例如,以下内容将不会编译:

My problem is that multi_index treats elements in the container as constants (in order to keep the integrity of all of the indices). For example, the following won't compile:

void main() {
    // put some data in the container
    MyDataContainer container;
    CanBeMultiIndexed e1(1, "one"); // conto'r not shown in class definition for brevity
    CanBeMultiIndexed e2(2, "two");

    container.insert(e1);
    container.insert(e2);

    // try to modify data
    MyDataContainer::nth_index<1>::type::iterator iter = container.get<1>().find(1);
    iter->data.some_value = 5;  // constness violation
}

我不能使用 replace()方法,因为复制有效负载类非常昂贵.我知道 modify()方法,但是使用它似乎很麻烦,因为在我的真实程序中,"payload"类可能包含许多字段,并为每个字段编写一个仿函数没问题.

I cannot use the replace() method, as it is expensive to copy the payload class. I'm aware of the modify() method, but using it seems cumbersome, since in my real program, the "payload" class may contain numerous fields, and writing a functor for each and every one it out of the question.

有什么建议吗?

编辑:在尝试了一些之后,我尝试用shared_ptr将数据元素替换为 MutableAndExpensiveToCopy :

After some playing around, I've tried replacing the data element with a shared_ptr to MutableAndExpensiveToCopy:

struct CanBeMultiIndexed
{
    // "Payload" - its fields will never be used as indices
    boost::shared_ptr<MutableAndExpensiveToCopy> data;

    // Indexes        
    int         id;
    std::string label;
}

这行得通,我能够编译我的 main(),包括修改数据的代码:

This worked, and I was able to compile my main() including the data-modifying code:

void main() {
    ...
    iter->data->some_value = 5;  // this works
    ...
}

这几乎给了我我想要的东西,但是我不确定为什么会起作用,所以:

This pretty much gives me what I wanted, but I'm not sure why this works, so:

  1. 此代码是否符合我的预期,还是我缺少一些警告?
  2. 这怎么起作用?shared_ptr的常量性不适用于其-> 运算符吗?

推荐答案

首先, ImMutableAndExpensiveToCopy 恰恰是相反的--mutable,因为您正在尝试更改其内容.例子.简单尝试一下:

First of all, ImMutableAndExpensiveToCopy seems precisely to be the opposite --mutable, since you're trying to change its contents in the example. Try simply this:

struct CanBeMultiIndexed
{
    mutable ImMutableAndExpensiveToCopy data;
    int         id;
    std::string label;
}

(为了保持一致性,可能会更改名称 ImMutableAndExpensiveToCopy .)

(and possibly change the name ImMutableAndExpensiveToCopy for consistency.)

这篇关于避开Boost Multi-Index容器的常量元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆