【发布时间】: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
...
}
这几乎给了我想要的东西,但我不确定为什么会这样,所以:
- 此代码是否符合我的预期,还是我遗漏了一些警告?
- 这是怎么工作的? shared_ptr 的常量是否不适用于其
->运算符?
【问题讨论】:
标签: c++ boost boost-multi-index