2015-04-06 12 views
6

Stavo verificando il sovraccarico dell'operatore in C++ e ho trovato qualcosa che non mi aspettavo e ho qualche dubbio a riguardo.Errore di compilazione del compilatore di copiatura esplicita

mio costruttore di copia è dichiarata e implementato come come

explicit Vector(const Vector& v); 

Vector::Vector(const Vector& v) : 
_x(v._x), _y(v._y), _z(v._z) {} 

allora sto sovraccaricare gli operatori di assegnazione composti

Vector Vector::operator+(const Vector& v) const 
{ 
    Vector tmp(*this); 
    tmp += v; 
    return tmp; 
} 

Vector Vector::operator-(const Vector& v) const 
{ 
    Vector tmp(*this); 
    tmp -= v; 
    return tmp; 
} 

tuttavia, nei return dichiarazioni che ho ottenuto un errore che dice no matching constructor for initialization of 'Vector'.

Poiché l'unica cosa che ho aggiunto al mio costruttore era la parola chiave explicit, l'ho cancellata e il codice viene compilato bene, perché?

Ho anche stato il controllo novità da C++ 11 e si è verificato che posso dichiarare il mio costruttore come un movimento costruttore

explicit Vector(const Vector&& v); 

e il codice viene compilato bene. Se lo faccio, devo avere sia copia che muovere i costruttori?

explicit Vector(const Vector& v); 
explicit Vector(const Vector&& v); 

o semplicemente avere il costruttore di spostamenti funzionerà correttamente? Se voglio attenermi a C++ 11, qual è l'approccio corretto da seguire?

+0

possibile duplicato di [Costruttore di copie esplicite] (http://stackoverflow.com/questions/11480545/explicit-copy-constructor) – Predelnik

+0

Molto probabilmente '+ =' e '- =' stanno facendo una copia implicita che causa la errore. – NathanOliver

+0

Non una risposta, ma un commento sul tuo codice. Non vi è alcun motivo per definire un tale costruttore di copia, poiché quelli predefiniti faranno esattamente lo stesso. Di solito c'è anche ragione per dichiarare esplicitamente un costruttore di copia, poiché la sua finalità è di impedire conversioni di tipo implicito. – MikeMB

risposta

5

È definito un costruttore di copia esplicita, ma le funzioni

Vector Vector::operator+(const Vector& v) const 

e

Vector Vector::operator-(const Vector& v) const 

deve tornare per valore, e non può più, a causa di explicit (in altre parole, non possono copiare tmp nell'oggetto restituito).

Ho anche stato il controllo novità da C++ 11 e si è verificato che posso dichiarare il mio costruttore come un movimento costruttore explicit Vector(const Vector&& v); e il codice viene compilato bene. Se lo faccio, devo avere sia copia che muovere i costruttori?

Non sono sicuro di capire cosa intendi qui. Avrai lo stesso problema se dichiari solo un costruttore di spostamento esplicito (che impedirà al compilatore di generare un costruttore di copie predefinito). Non sono in grado di produrre un codice "compilabile".

+0

Penso di aver incasinato le cose. Il valore restituito, è un lvalue o un valore? Se è un ** valore **, non è possibile, invece di copiare 'tmp', usare il costruttore di movimento o spostare un'operazione che è nuova in C++ 11 ?. Se è un ** lvalue ** la funzione copierà sempre il valore? c'è qualche ottimizzazione dal compilatore? – BRabbit27

+3

@ BRabbit27 il ritorno è un valore massimo e il compilatore esegue l'ottimizzazione ogni volta che è possibile (si chiama * ottimizzazione del valore di ritorno * o RVO). Tuttavia, se dichiarate espliciti i costruttori move/copy ', anche se l'ottimizzazione è in linea di principio possibile, il compilatore si lamenta ancora del business' esplicito'. Questo è principalmente dovuto al fatto che il compilatore esegue prima l'analisi della correttezza del tuo programma, quindi applica le ottimizzazioni. Il codice dovrebbe essere C++ valido prima della fase di ottimizzazione. – vsoftco

+1

@ BRabbit27 e in C++ 11, il compilatore prima tenta di spostare l'oggetto restituito (se possibile), in caso contrario, cerca un costruttore di copia per copiarlo, e se non lo trova ancora emette un errore . Questo è il caso qui, non hai costruttori impliciti di copia/spostamento. – vsoftco

0

Per restituire un oggetto in base al valore è necessario eseguire una costruzione di copia implicita. Rendere esplicito il costruttore della copia lo impedisce.

Questo è vero indipendentemente dal fatto che il compilatore scelga di non richiamare il costruttore di copie (ad esempio l'ottimizzazione del valore di ritorno).

Problemi correlati