一時的なstd :: map temp
の内容を移動のセマンティクスを使用して別のstd :: map m
に挿入して、一時的な値がコピーされず再利用されるようにすることは可能ですか? ?
あるとしましょう:
std::map<int, Data> temp;
std::map<int, Data> m;
temp
からm
に値をコピーする1つの方法は次のとおりです。
m.insert(temp.begin(),temp.end());
コピーする代わりにmovetemp
要素をm
にするにはどうすればよいですか?
ヒント:最初に更新を読み取ります!
現在のC++ 11標準とC++ 14ドラフトは、この機能を有効にするメンバー関数を提供していません。 lavrが示唆したように、あなたはまだ書くことができます
_m.insert(make_move_iterator(begin(temp)),
make_move_iterator(end (temp)));
_
valuesをソースコンテナーから宛先コンテナーに移動します。ただし、コンテナノードもキーも移動されません。これには、メモリ割り当てが必要です(少なくとも宛先マップで新しいノードを作成するため)。ソースコンテナ内の要素の数は変わりません。コピーの背後にある理由は単純です。_std::map
_の値の型は_std::pair<const Key,T>
_です。また、_const Key
_から移動すると、基本的にはキーがコピーされます(_const Key &&
_を受け取るKey
コンストラクターをオーバーロードした場合を除き、適切な理由が考えられません)。
コンテナ間でデータを移動する必要がある場合は、_std::list
_ではなく_std::map
_の使用を検討してください。 メンバー関数splice
があり、要素をあるリストから別のリストに一定の時間で移動します。
UPDATE:
C++ 17以降、関数 std::map::merge()
があり、基本的には実際の要素を移動またはコピーせずに、1つの_std::map
_のすべての要素を別の_std::map
_に入れます。 、ただし内部ポインタのみを再ポイントする。 C++ 98以降に存在するstd::list::splice()
によく似ています。
だからあなたは書くかもしれません
_m.merge( temp );
_
あなたの目標を達成するために。これは、すべての要素を1つのコンテナーから別のコンテナーにコピーまたは移動するよりも効率的です。
しかし注意してください!競合するキーは解決されません。一致するキーの場合、何も行われません。
試していませんが、 std :: move_iterator が役立つと思います:
using it = std::map<int, Data>::iterator;
using mv = std::move_iterator <it>;
m.insert(mv(temp.begin()),mv(temp.end()));
これは可能ではないと思います。他のコンテナでは、std::move_iterator
アダプタですが、マップのキーがconstであるため機能しません。
つまり、マップから要素を1つずつ移動することはできません。これにより、マップで許可されていないキーが変更される可能性があります。
また、1つのマップから別のマップに一括移動するだけの方法はありません。リストはスプライシングをサポートしていますが、ツリーはサポートしていないようです。