イベントに応じて頻繁に更新されるため、コピーするのに費用がかかりますが、変更可能でなければならないデータクラスがあります。また、このようなクラスを多数保持するためのマルチインデックス コンテナーも必要です。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 の constness はその
->
演算子に適用されませんか?