EDIT:
des trois formes décrites dans ce fil, celui qui évite des copies inutiles est la forme proposée par @ max66. Le code suivant et sa sortie capte ces trois formes dans l'action
#include <iostream>
#include <map>
using namespace std;
struct FooStruct
{
FooStruct()
{
cout << "FooStruct Default Constructor" << endl;
}
FooStruct(const FooStruct& other)
{
this->a = other.a;
this->b = other.b;
cout << "FooStruct Copy Constructor" << endl;
}
FooStruct(int a, int b)
{
this->a = a;
this->b = b;
cout << "FooStruct Parametrized Constructor" << endl;
}
int a;
int b;
};
sortie:
foo.emplace<int, FooStruct>(0, {1, 2})
FooStruct Parametrized Constructor
FooStruct Copy Constructor
fooMap.emplace(make_pair<int, FooStruct>(1, { 2, 3 }))
FooStruct Parametrized Constructor
FooStruct Copy Constructor
FooStruct Copy Constructor
fooMap.emplace(std::piecewise_construct, std::forward_as_tuple(2), std::forward_as_tuple(2, 4))
FooStruct Parametrized Constructor
============
ORIGINAL (MAL)
J'étais un peu paresseux et je n'ai pas essayé de creuser plus avant de poster la question. Je vois maintenant que toutes ces trois formes (la troisième forme vient du commentaire de @ max66) sont équivalentes en ce qu'elles évitent toutes trois la création d'une copie temporaire de FooStruct
.
#include <iostream>
#include <map>
using namespace std;
struct FooStruct
{
FooStruct() { cout << "FooStruct Default Constructor" << endl; }
FooStruct(int a, int b) { this->a = a; this->b = b; cout << "FooStruct Parametrized Constructor" << endl; }
int a;
int b;
};
int main()
{
map<int, FooStruct> fooMap;
fooMap.emplace<int, FooStruct>(0, {1, 2});
fooMap.emplace(make_pair<int, FooStruct>(1, { 2, 3 }));
fooMap.emplace(std::piecewise_construct, std::forward_as_tuple(2), std::forward_as_tuple(2, 4));
return 0;
}
Le code ci-dessus (construite avec Visual C++ 2015) produit la sortie suivante:
FooStruct Parametrized Constructor
FooStruct Parametrized Constructor
FooStruct Parametrized Constructor
PS: je ne vérifie que chaque ligne de la sortie ci-dessus correspond à un seul appel emplace ci-dessus
La différence est 'make_pair' utilise la sémantique de constructeur de déplacement de' pair', tandis que d'autres méthodes appellent le constructeur du template. – Swift
Qu'en est-il de 'fooMap.emplace (std :: piecewise_construct, std :: forward_as_tuple (0), std :: forward_as_tuple (1, 2));'? – max66
@ max66: Voulez-vous dire que votre forme est meilleure que les deux mentionnés ci-dessus? Si oui, pouvez-vous expliquer pourquoi c'est le cas? – DigitalEye