2012-12-28 13 views
8

Da this di riferimento, permette una const rvalue come una mossa costruttoreSpostare firma costruttore

Type::Type(const Type&& other); 

Come può un oggetto mobile essere const? Anche se questo fosse tecnicamente permesso, c'è un caso in cui tale dichiarazione sarebbe utile?

+4

Risposta semplice: No, non c'è, in quanto sconfigge l'intero scopo della semantica del movimento. Si noti inoltre che '&&' non dice necessariamente "mobile". Dice solo "riferimento di rvalore". E * MoveConstructible * ricade sulla copia se non ci sono matrici di movimento, quindi si potrebbe dire che il comando "T const &&" potrebbe semplicemente copiare, ma eh. – Xeo

+0

Bene, 'Type' può dichiarare una variabile' mutable' e 'mutable' * può * essere modificata dai costruttori' const' move. Quindi un costruttore di 'const' move potrebbe semplicemente fare una copia superficiale dell'oggetto (mentre un costruttore di copia potrebbe fare una copia profonda) e impostare un flag booleano' mutabile' chiamato 'dead' o qualcosa di simile a' true' sul oggetto. Quindi le funzioni di 'Type' (soprattutto il distruttore) controllerebbero quel flag. È una sciocchezza? –

risposta

9

Come può un oggetto mobile essere const?

Non può, ma non è quello che dice la lingua. Il linguaggio dice che un costruttore con quella firma è un "costruttore di mosse", ma questo non significa che l'argomento venga spostato, significa semplicemente che il costruttore soddisfa i requisiti di un "costruttore di mosse". Non è necessario un costruttore di movimento per spostare nulla, e se l'argomento è const non può.

Esiste un caso in cui tale dichiarazione sarebbe utile?

Sì, ma non molto spesso. Può essere utile se si desidera evitare che un altro costruttore venga selezionato dalla risoluzione di sovraccarico quando un argomento const viene passato come argomento.

struct Type 
{ 
    template<typename T> 
    Type(T&&); // accepts anything 

    Type(const Type&) = default;  
    Type(Type&&) = default; 
}; 

typedef const Type CType; 

CType func(); 

Type t(func()); // calls Type(T&&) 

In questo codice temporanea tornato da func() non corrisponderanno parametri copia o spostamento costruttori esattamente, così si chiama il costruttore modello che accetta qualsiasi tipo. Per evitare che questo si potrebbe fornire un sovraccarico di diverso prendendo un rvalue const, e sia delegato al costruttore di copia:

Type(const Type&& t) : Type(t) { } 

Oppure, se si vuole evitare che il codice di compilazione, definirlo come cancellati:

Type(const Type&& t) = delete; 

Vedere https://stackoverflow.com/a/4940642/981959 per esempi dello standard che utilizzano un riferimento constval.

Problemi correlati