3

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

1 に答える 1

6

まず第一にImMutableAndExpensiveToCopy、この例ではその内容を変更しようとしているため、まさに反対の --mutable のようです。これを簡単に試してください:

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

(そしてImMutableAndExpensiveToCopy、一貫性のために名前を変更する可能性があります。)

于 2011-04-03T13:14:36.213 に答える