1

Move Semantics と [r|l]value 参照をいじって、実際のプログラムでそれらを使用する方法を学んでいます。次のコードを検討してください。

// Item is a heavy class having move ctor and assignment but no copy. 
std::map<std::string, Item*> lookup;
std::forward_list<Item> items;
void FooClass::addItem(Item&& d) {
    if (lookup.find(d.getName()) == lookup.end()) {
        lookup[d.getName()] = &d;    //<== not safe after move?
        items.push_front(std::move(d));
    }
}

のアドレスを取得Item&&して、ポインターに格納します。次に、そのデータをstd::forward_list( items) に移動します。move 代入を呼び出してもオブジェクトのアドレスには影響しないと思います。あれは正しいですか?のコンテンツはd移動後に無効になりますが。それは、ルックアップ テーブル ( lookup) の内容が正しくありません。

a) ルックアップ アイテムの追加と b) 実際のデータの移動の順序を変更する必要があると想定しています。上記のコードは正気ではありません。これは正しいです?

また、なぜそこで言わなければならないのかわかりませんstd::move。コンパイラは、それdが右辺値参照であることを認識している必要があります。std::forward_list<T>::push_front(T&&)したがって、割り当てを呼び出して移動する必要があります...

4

2 に答える 2

1

次のように、値で保存するようにitems変更します。lookupItem

using Lookup = std::map<std::string, Item>;
Lookup lookup;

void addItem(Item&& d)
{ lookup.insert(std::pair<std::string const&, Item&&>{d.getName(), std::move(d)}); }
于 2013-08-07T21:42:59.910 に答える