【问题标题】:Getting around Boost Multi-Index container's constant elements绕过 Boost Multi-Index 容器的常量元素
【发布时间】:2011-07-28 13:30:45
【问题描述】:

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

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 将容器中的元素视为常量(以保持所有索引的完整性)。例如,以下代码不会编译:

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() 方法,但是使用它似乎很麻烦,因为在我的实际程序中,“有效负载”类可能包含许多字段,并且为每一个都编写一个函子是不可能的。

有什么建议吗?

编辑:经过一番尝试,我尝试用 shared_ptr 将数据元素替换为MutableAndExpensiveToCopy

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

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

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

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

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

  1. 此代码是否符合我的预期,还是我遗漏了一些警告?
  2. 这是怎么工作的? shared_ptr 的常量是否不适用于其-&gt; 运算符?

【问题讨论】:

    标签: c++ boost boost-multi-index


    【解决方案1】:

    首先,ImMutableAndExpensiveToCopy 似乎正好相反 --mutable,因为您试图在示例中更改其内容。试试这个:

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

    (并且可能更改名称 ImMutableAndExpensiveToCopy 以保持一致性。)

    【讨论】:

    • @Joaquin - ImMutableAndExpensiveToCopy 我的意思是说“我是可变的并且复制成本很高”。我会修正这个例子来说明这一点。
    • 好的,我现在明白了 :-) 无论如何,mutable- 排位赛能解决你的问题吗?
    • @Joaquin - 不。如documentation 中所述,迭代器返回自,例如根据定义,find() 是 const。这是为了保证索引的完整性。顺便说一句,AFAIK,类/结构成员默认情况下是可变的,所以 mutable 限定符是多余的。
    • @bavaza:我很确定 Joaquin 知道迭代器是恒定的,因为他是 Boost.MultiIndex 库的作者。您是否尝试过他的建议,或者只是认为它不起作用?您似乎认为mutableconst 是相反的,事实并非如此。默认情况下,成员是不可变的。
    • @Juaquin, Interjay:我试过mutable,问题解决了。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-14
    • 1970-01-01
    • 2010-12-21
    • 2012-06-27
    • 1970-01-01
    相关资源
    最近更新 更多