Primo: dove sono definiti std::move
e std::forward
? So cosa fanno, ma non riesco a trovare la prova che sia necessaria un'intestazione standard per includerli. In gcc44 talvolta è disponibile std::move
, e talvolta non lo è, quindi sarebbe utile una direttiva di inclusione definitiva.Alcuni chiarimenti sui riferimenti di rvalore
Quando si implementa la semantica del movimento, la sorgente viene presumibilmente lasciata in uno stato indefinito. Questo stato dovrebbe necessariamente essere uno stato valido per l'oggetto? Ovviamente, devi essere in grado di chiamare il distruttore dell'oggetto ed essere in grado di assegnarlo con qualunque mezzo la classe esponga. Ma dovrebbero essere valide altre operazioni? Suppongo che quello che sto chiedendo sia, se la tua classe garantisce certe invarianti, dovresti sforzarti di far rispettare quegli invarianti quando l'utente ha detto che non gli importa più di loro?
Avanti: quando non ti interessa la semantica del movimento, ci sono dei limiti che farebbero preferire un riferimento non const su un riferimento di rvalue quando si gestiscono i parametri di funzione? void function(T&);
su void function(T&&);
Dal punto di vista del chiamante, essere in grado di passare le funzioni valori temporanei è talvolta utile, quindi sembra che si debba concedere tale opzione ogni volta che è fattibile. E i riferimenti di valore sono essi stessi lvalue, quindi non puoi inavvertitamente chiamare un costruttore di mosse invece di un costruttore di copie, o qualcosa del genere. Non vedo un rovescio della medaglia, ma sono sicuro che ce n'è uno.
Che mi porta alla mia ultima domanda. Non è ancora possibile associare i provvisori a riferimenti non const. Ma puoi vincolarli a riferimenti non costanti. E quindi puoi passare quel riferimento come riferimento non const in un'altra funzione.
void function1(int& r) { r++; }
void function2(int&& r) { function1(r); }
int main() {
function1(5); //bad
function2(5); //good
}
Oltre al fatto che non fa nulla, c'è qualcosa di sbagliato in quel codice? Ovviamente il mio istinto non lo dice, dal momento che cambiare i riferimenti di valore è un po 'il punto centrale della loro esistenza. E se il valore passato è legittimamente const, il compilatore lo prenderà e ti urlerà contro. Ma da tutte le apparenze, questa è una soluzione di un meccanismo che presumibilmente è stato messo in atto per una ragione, quindi vorrei solo la conferma che non sto facendo nulla di sciocco.
Grazie per l'elaborata risposta. Penso di capire le cose meno di prima, ma non per colpa tua. Secondo questo articolo, una funzione come 'void f (int &&);' non può accettare lvalues a meno che non siano espressi espressi? Questo non è sicuramente il comportamento che ho visto, quindi presumo che questa sia una lacuna in gcc-4.4 L'implementazione, che rende tutti i test che ho fatto per capire come tutto interagisca praticamente senza valore: -/ –
@Dennis, yep che è stato modificato nella bozza di lavoro qualche tempo fa: 'int &&' non si associa implicitamente a è troppo pericoloso –
Il link "questo articolo" è morto. Puoi cambiarlo in uno attuale? –