Newsgroup: it.comp.lang.c++
Titolo: STL library: copia e spostamento

Come ho scritto nel post poco più sotto sto facendo uno studio sulle collezioni della STL library. Tutto è partito dall'esigenza di spostare oggetti tra liste diverse (delle stesso tipo), avendo sempre e comunque un'istanza unica e univoca dell'elemento (niente copie e duplicati).
 
Per esempio: Abbiamo una classe Foo che contiene all'interno una semplice stringa "messaggio". I costruttori e operatori per copia e spostamento sono tutti implementati. Che differenze vi aspettate tra questo codice:
 
  typedef std::list<Foo> foo_list;
 
  foo_list collection1 = {
    std::move(Foo{"Hello"}),
    std::move(Foo{"collections"}),
    std::move(Foo{"!!"})
  };
 
  foo_list collection2 = std::move(collection1);
 
 
e questo?
 
  typedef std::list<std::shared_ptr<Foo>> foo_list;
 
  foo_list collection1 = {
    std::make_shared<Foo>("Hello"),
    std::make_shared<Foo>("collections"),
    std::make_shared<Foo>("!!"),
  };
 
  foo_list collection2 = std::move(collection1);

Il 07/10/19 07:47, _merlinO_ ha scritto:

che il caso 2 sia piu performante di 1 dipende da Foo(Foo&&); come e' 
fatto (quanta roba sposta e come la sposta)
Occorre anche tenere conto che shared_ptr va su heap,generalmente piu 
lento come costruzione rispetto allo stack e comunque piu lento di 
unique_ptr
Forse per una lista condivisa,se e' quello che si vuole ottenere (ma 
dipende dal problema), non e'  meglio un shared_ptr<foo_list>
senza stare a creare singoli elementi shared_ptr ?
 
 
 
 
 
 
-- 
|___|

 senza stare a creare singoli elementi shared_ptr ?
 
L'esempio sposta tutta la lista, ma nel mio caso reale dovevo muovere solo determinati elementi che rispondono a una condizione. 
Comunque la differenza è impressionante: 
http://cpp.sh/2ch2v
 
 
*** No pointers (Primo esempio) ***
Constructor Foo() called for "Hello"
Move constructor Foo(Foo&& other) called for "Hello"
Constructor Foo() called for "collections"
Move constructor Foo(Foo&& other) called for "collections"
Constructor Foo() called for "!!"
Move constructor Foo(Foo&& other) called for "!!"
Assignment operator Foo& operator=(const Foo& other) called for "Hello"
Copy constructor Foo(const Foo& other) called for "Hello"
Assignment operator Foo& operator=(const Foo& other) called for "collections"
Copy constructor Foo(const Foo& other) called for "collections"
Assignment operator Foo& operator=(const Foo& other) called for "!!"
Copy constructor Foo(const Foo& other) called for "!!"
Destructor ~Foo() called for "!!"
Destructor ~Foo() called for "collections"
Destructor ~Foo() called for "Hello"
Destructor ~Foo() called for "???moved???"
Destructor ~Foo() called for "???moved???"
Destructor ~Foo() called for "???moved???"
Destructor ~Foo() called for "Hello"
Destructor ~Foo() called for "collections"
Destructor ~Foo() called for "!!"
 
*** With pointers (Secondo esempio) ***
Constructor Foo() called for "Hello"
Constructor Foo() called for "collections"
Constructor Foo() called for "!!"
Destructor ~Foo() called for "Hello"
Destructor ~Foo() called for "collections"
Destructor ~Foo() called for "!!"