considerare questo programma:elementi Inserire le std :: map senza copiare in più
#include <map>
#include <string>
#define log magic_log_function // Please don't mind this.
//
// ADVENTURES OF PROGO THE C++ PROGRAM
//
class element;
typedef std::map<int, element> map_t;
class element {
public:
element(const std::string&);
element(const element&);
~element();
std::string name;
};
element::element(const std::string& arg)
: name(arg)
{
log("element ", arg, " constucted, ", this);
}
element::element(const element& other)
: name(other.name)
{
name += "-copy";
log("element ", name, " copied, ", this);
}
element::~element()
{
log("element ", name, " destructed, ", this);
}
int main(int argc, char **argv)
{
map_t map1; element b1("b1");
log(" > Done construction.");
log(" > Making map 1.");
map1.insert(std::pair<int, element>(1, b1));
log(" > Done making map 1.");
log(" > Before returning from main()");
}
Esso crea alcuni oggetti sulla pila e insert
li s in un contenitore std::map
, creando due copie extra temporanei nel processo:
element b1 constucted, 0x7fff228c6c60
> Done construction.
> Making map 1.
element b1-copy copied, 0x7fff228c6ca8
element b1-copy-copy copied, 0x7fff228c6c98
element b1-copy-copy-copy copied, 0x232d0c8
element b1-copy-copy destructed, 0x7fff228c6c98
element b1-copy destructed, 0x7fff228c6ca8
> Done making map 1.
> Before returning from main()
element b1 destructed, 0x7fff228c6c60
element b1-copy-copy-copy destructed, 0x232d0c8
possiamo sbarazzarci di una chiamata al costruttore copia in più cambiando la firma std::pair
-std::pair<int, element&>
, tuttavia, il secondo è ancora provvisorio cr eated e immediatamente distrutte:
element b1 constucted, 0x7fff0fe75390
> Done construction.
> Making map 1.
element b1-copy copied, 0x7fff0fe753c8
element b1-copy-copy copied, 0x1bc4098
element b1-copy destructed, 0x7fff0fe753c8
> Done making map 1.
> Before returning from main()
element b1 destructed, 0x7fff0fe75390
element b1-copy-copy destructed, 0x1bc4098
C'è un modo per rendere std::map
basta prendere un oggetto sulla pila per riferimento e fare una singola copia interna di esso?
Il modo più efficiente sarebbe 'map1.emplace (1," b1 ");'. Ma non è ancora supportato ovunque. La cosa migliore è 'map1 [1] =" b1 ";', sebbene abbia una semantica leggermente diversa. –
Si noti inoltre che 'map_t :: value_type' è ** not **' std :: pair '! –
'#include" log.cpp "' è * davvero * spaventoso. –