2016-05-07 5 views
1

Я хочу сохранить ряд объектов MyItem, , полученных от Qt::QGraphicsItem, в std::unordered_map. Как я понял, Qt::QGraphicsItemне подлежит копированию: экземпляр копии является закрытым.Как я могу на месте построить объект некоторого класса в std :: unorderd_map?

Это прекрасно; Я не хочу копировать MyItem. Но мне нужно было бы построить 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")); 

Я получаю эту ошибку (вырезать):

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 (соответствующийKey), std :: forward_as_tuple (3, 3.14,« hello »)); вместо –

ответ

3

Вы строите значение MyItem, которое emplace затем пытается скопировать. Точка функции emplace должна оставить конструкцию до map. Это осложняется тем, что вам необходимо пройти pair, где вы хотите отложить строительство second.

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.

+2

Это рабочее решение, но когда они сказали C++ 11 упростит использование C++, я думаю, они взяли нас за дураков. –

+2

@JohnZwinck Ну, вы можете хотя бы сделать это сейчас - на C++ 08 вы не смогли. И C++ 17 предоставит 'try_emplace', который значительно уменьшит уродство. http://en.cppreference.com/w/cpp/container/unordered_map/try_emplace –

1

Вы код будет работать, если вы добавите конструктор перемещения к MyItem:

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'. Я добавил возможную реализацию в свой ответ. –

 Смежные вопросы

  • Нет связанных вопросов^_^