std::map emplace sans copier la valeur

Le C++11 std::map<K,V> type a un emplace fonction, comme dans beaucoup d'autres conteneurs.

std::map<int,std::string> m;

std::string val {"hello"};

m.emplace(1, val);

Ce code fonctionne comme annoncé, emplacing la std::pair<K,V> directement, cependant, il en résulte une copie de key et val lieu.

Est-il possible de emplace le type de la valeur directement dans la carte ainsi? Peut-on faire de mieux que de déplacer les arguments dans l'appel à emplace?


Voici un plus approfondie exemple:

struct Foo
{
   Foo(double d, string s) {}
   Foo(const Foo&) = delete;
   Foo(Foo&&) = delete;
}

map<int,Foo> m;
m.emplace(1, 2.3, string("hello")); //invalid
  • J'ai lu un tas de documents et d'en venir à la conclusion qu'il n'est pas possible. Cependant, je ne suis pas le plus expérimenté, développeur C++, donc envie de courir il passé certains gourous ici, dans l'espoir que je me trompe. Pouvez-vous aider?
  • ok, lecture de en.cppreference.com/w/cpp/container/map/emplace
  • Voulez-vous dire une copie supplémentaire? val est une lvalue, par conséquent, une copie devra être fait à un certain point.
  • imaginez la valeur a d'autres plus complexes de type et qu'il n'était ni copiable, ni mobiles (et donc, bien sûr, ne peut pas être présenté comme une lvalue, ni déplacés/cast de référence rvalue). Je veux que la valeur des arguments du constructeur directement à une sorte de emplace fonction de sorte qu'il est instancié à l'aide de transfert parfait et (probablement) la mise en place de nouvelles à l'intérieur de la carte.
  • J'ai ajouté un autre exemple.
  • Voir en.cppreference.com/w/cpp/container/map/emplace pour un exemple 🙂
  • naturellement, j'ai eu RTFM, mais sans savoir ce piecewise_construct et forward_as_tuple faire, ce n'était pas évident qu'ils se sont adressés à mon problème. La lecture de la documentation sur pair que Prétorienne lié à offert la pièce manquante (pun intended).
  • Si je me souviens bien, le emplace fonctionnalité de map, et de tous les autres unique-conteneurs de clés, est en fait plus lentement que l'insert standard. Pour une raison quelconque, la norme exige (je n'ai pas une citation, mais c'est ce que Scott Meyers a montré lors d'une conférence) que le nouvel objet est alloué et déplacé avant de vérifier que la clé n'existe pas encore. Si il existe déjà, l'objet est détruit à nouveau. Bottomline: sauf si je suis en tort, ne pas utiliser de emplace 🙂
  • J'ai retrouvé sur youtube: youtube.com/watch?v=smqT9Io_bKo#t=46m00s
  • merci pour le lien. Dans mon cas, la clé est unique sur insérer (emplace) donc je vais garder la solution donnée.
  • remarque Importante!
  • Comme le constructeur pourrait jeter, il a besoin d'un fort exception de garantie, mais le fait de les insérer de façon régulière, je ne vois pas comment cela pourrait être plus lentement.
  • Ce qui rend ce code non valide pour g++5.4 (il essaie d'utiliser le supprimer copyconstructor), mais valable pour les versions ci-dessus ?

InformationsquelleAutor Drew Noakes | 2015-01-15