2016-10-01 8 views
3

std::unordered_setstd::unique_ptr<T>であるとします。セットの要素を別の場所に移動することはできますか?STLコンテナから移動専用のタイプを取得するにはどうすればよいですか?

#include <unordered_set> 
#include <iostream> 
#include <memory> 
#include <vector> 

int main() 
{ 
    std::unordered_set<std::unique_ptr<int>> mySet; 

    mySet.insert(std::make_unique<int>(1)); 
    mySet.insert(std::make_unique<int>(2)); 
    mySet.insert(std::make_unique<int>(3)); 

    std::vector<std::unique_ptr<int>> myVector; 

    for (auto&& element : mySet) 
    { 
     std::cout << *element << std::endl; 
     //myVector.push_back(element); won't compile as you can only get a const ref to the key 
    } 
} 

私はこれをやりたいけどstd::shared_ptrを使用するように減少していたコードの非常に実用的な例があります。あなたは別の(より良い?)代替手段を知っていますか?

+1

注::代わりにベクトルです。 [ノードベースのコンテナ](http://en.cppreference.com/w/cpp/container/node_handle)に特有のものです。また、移動に成功すると、move-fromオブジェクトは挿入や検索などのために読み込みが無効になっているため、未定義の動作を設定する可能性があるので注意してください。したがって、コンテナの使用には注意が必要ですまったく。 – metal

+0

@metal私はおそらく何か間違っていますが、ベクターとのコンパイルエラーは同じです。http://coliru.stacked-crooked.com/a/51af3ac220c44619を参照してください。編集:私の悪い、 'std :: move'で動作します。ありがとう!新しいコード:http://coliru.stacked-crooked.com/a/95cb8a827d587723 – matovitch

答えて

8

C++ 03、C++ 11、およびC++ 14では、直接ではありません。あなたが好きなものにするためにタイプを変更する必要があると思います。これにより

template <class T> 
struct handle { 
    mutable std::unique_ptr<T> owning_ptr; 
    T* observing_ptr; // enforce that observing_ptr == owning_ptr.get() on construction 

    // define operator<, hash, etc. in terms of the observing ptr 
}; 

、あなたが書くことができます。

std::unordered_set<handle<int>> mySet; 
// initialize as appropriate 

for (auto& elem : mySet) { 
    myVector.push_back(std::move(elem.owning_ptr));   
} 
mySet.clear(); 

私たちはどんないじりいないので、これはまだ明確に定義された動作になりますコンテナの内部構造のうち、観察ポインタはclear()の最後まで有効ですが、ちょうどmyVectorがそれを所有しています。 C++ 17では


、我々はextract()の助けを借りて、直接、より簡単にこれを行うことができます。mySet`は `のstdた`場合、この問題が発生しないことを

for (auto it = mySet.begin(); it != mySet.end(); 
{ 
    std::cout << **it << std::endl; 
    myVector.push_back(std::move(
     mySet.extract(it++).value())); 
} 
+0

コンテナに、スマートポインタと注文に同意するダムポインタのような変更可能なタグ付きのユニオン形式と、スワップする操作スマートから帰ってくる間、スマートからダムへ。スマートを抽出し、ダムを消去し、ボブはあなたの叔父です。 – Yakk

+0

@ヤククあなたの一歩先を行く:)それは組合ではないが、そうかもしれない。 – Barry

+1

'handle >'ではなく 'handle 'でなければなりませんか? – ArchbishopOfBanterbury

関連する問題