In C++, se si dispone di un ciclo for che "copie" oggetti di un tipo definito dall'utente utilizzando un costruttore mossa [...]
Prima di tutto, un costruttore mossa viene utilizzato per move-constructing, che di solito significa che non stai "copiando": puoi can realizzare lo spostamento come copia - in effetti, una classe che è copy-constructible è anche move-constructible - ma allora perché definire esplicitamente un costruttore di move?
[...] fa alcuna differenza se si utilizza ++ i o i ++ come contatore di loop?
Dipende da cosa è i
. Se si tratta di un oggetto scalare, come un int
, non c'è alcuna differenza.
Se i
è una classe di tipo iteratore, d'altra parte, ++i
dovrebbe essere più efficiente (su un terreno puramente teorica), perché l'implementazione di operator ++
non dovrà creare una copia del iteratore da restituire prima l'iteratore stesso viene incrementato.
Qui, per esempio, è il modo in stdlibC++ definisce gli operatori di incremento per il tipo iteratore di un std::list
:
_Self&
operator++()
{
_M_node = _M_node->_M_next;
return *this;
}
_Self
operator++(int)
{
_Self __tmp = *this;
_M_node = _M_node->_M_next;
return __tmp;
}
Come si può vedere, la versione suffisso (quella di accettare un manichino int
) ha più lavoro da fare: ha bisogno di creare una copia dell'iteratore originale da refurnare, quindi modificare il puntatore interno dell'iteratore, quindi restituire la copia.
D'altra parte, la versione del prefisso deve solo modificare il puntatore interno e restituire (un riferimento a) stesso.
Tuttavia, si tenga presente che quando si tratta di prestazioni, tutte le ipotesi devono essere sottoposte a backup mediante misurazione. In questo caso, non mi aspetto alcuna differenza sensata tra queste due funzioni.
Vedere anche la soluzione [Soluzione GotW # 2: Oggetti temporanei] di Herb Sutter (http://herbsutter.com/2013/05/13/gotw-2-solution-temporary-objects/). – jww