2016-05-07 4 views
1

私はMyItemQt::QGraphicsItemに由来するMyItemstd::unordered_mapに保存したいと思います。私が理解したように、Qt::QGraphicsItemはコピーできません:コピーコンストラクタはプライベートです。std :: unorderd_mapにあるクラスのオブジェクトをインプレースでどのように構築できますか?

これは問題ありません。私はMyItemをコピーしたくない。しかし、私はMyItemをインプレースで構築する必要があります。

MyItem::MyItem(int a, double b, std::string c); 

そして、これが私のstd::unordered_mapです:

std::unordered_map< KeyType, MyItem > myItemMap; 

KeyTypeはコピー可能と定置前に構築され、このライン、と間違っているもの:

myItemMap.emplace(correspondingKey, MyItem(3, 3.14, "hello")); 
MyItemは、このコンストラクタシグネチャを持っていると仮定すると、

このエラーが発生しました(カット):

use of deleted function 'MyItem::MyItem(const MyItem&)' 
    : first(std::forward<_U1>(__x)), second(__y) { } 
              ^
'MyItem::MyItem(const MyItem&)' is implicitly deleted because the default definition would be ill-formed: 

'QGraphicsItem::QGraphicsItem(const QGraphicsItem&)' is private 

myItemMap.emplace(...)の引数はどのように見えるのですか?

+0

'myItemMap.emplace(std :: piecewise_construct、std :: forward_as_tuple(correspondingKey)、std :: forward_as_tuple(3、3.14、" hello "));'代わりに –

答えて

3

emplaceがコピーしようとしているMyItemの値を作成しています。 emplace機能のポイントは、構成をmapのままにすることです。 secondの建設を延期する場合は、pairを渡す必要があるため、複雑になります。

myItemMap.emplace(std::piecewise_construct, 
      std::forward_as_tuple(correspondingKey), 
      std::forward_as_tuple(3, 3.14, "hello")); 

http://en.cppreference.com/w/cpp/container/unordered_map/emplaceを参照してください。あなたはMyItemに移動コンストラクタを追加する場合

+2

を使用してください。 C++ 11ではC++が使いやすくなりました。彼らは私たちを愚か者に連れて行ったと思います。 –

+2

@JohnZwinckさて、少なくとも今のところそれを行うことができます.C++では、できませんでした。そしてC++ 17は 'try_emplace'を提供して、醜さをかなり軽減します。 http://en.cppreference.com/w/cpp/container/unordered_map/try_emplace –

1

あなたのコードは動作します:

MyItem(MyItem&& old) 
    : Base(old.parentItem()) 
{ 
    for (QGraphicsItem* child : old.childItems()) { 
     child->setParentItem(this); 
    } 
    old.setParentItem(nullptr); 
} 

は、次にインスタンスが自動的に移動し、コピーされません。

+2

これは、 'QGraphicsItem'に移動コンストラクタが必要なことを意味しますか?それは、ドキュメント(http://doc.qt.io/qt-5.6/qgraphicsitem.html)によると、(それは私には分かりません)。 – dani

+1

@dani:いいえ、QGraphicsItemは移動コンストラクタを持つ必要はありません。単にMyItemが必要とするだけです。 'MyItem'ムーブコンストラクタを実装することができます。 'QGraphicsItem'の通常のコンストラクタを使います。私は私の答えに可能な実装を追加しました。 –

関連する問題