2015-05-05 11 views
8

Avendo questo insieme di oggetti e dichiarazioni:Non capendo C++ tipo non corrispondente: const Foo * a Foo * const &

QSet<Foo*> set; 
iterator QSet::insert(const T & value) //type of the function I want to call 
const Foo * get() const     //type of the function I use to get the argument 

set.insert(get());      //the line showing up as error 

ottengo l'errore "non noto di conversione per argomento 1 da 'const Foo *' a ' Foo * const & ". Credo di avere problemi a leggere questi tipi perché non ho idea di cosa dovrei fare per farlo funzionare.

Da quello che ho letto, la parola chiave const vale per il tipo alla sua sinistra, con l'eccezione di un const di livello superiore che può essere scritto alla sinistra del tipo si applica. La mia ipotesi sarebbe che devo convertire get() a un riferimento, ma non sono sicuro di come farlo.

+0

Questo non è "primo' const' ". 'get()' restituisce un puntatore a "' const Foo' ", non un puntatore' const'. – Barry

+0

Quindi la mia comprensione che un 'const' all'inizio si applica a tutto ciò che è alla sua destra era sbagliato? A che cosa si applica esattamente tale 'const '? –

risposta

7

Sembra che ci siano un paio di equivoci qui (sia dall'interrogante che da alcune risposte).

Primo, hai detto "La mia ipotesi sarebbe che devo convertire get() a un riferimento, ma non sono sicuro di come farlo". Proviamo a chiarire:

1) "Devo convertire get() a un riferimento" - In realtà, non lo fai!

iterator QSet::insert(const T & value) tiene effettivamente un riferimento. Ma è un riferimento al tipo T. Quindi la domanda è, "che cosa è il tipo T"?

In questo caso, T=Foo *. Così insert, in questo caso del modello, è in realtà:

iterator QSet::insert(Foo * const & value) - letto da destra a sinistra: insert prende un riferimento a un puntatore costante a un Foo.

2) "Non sono sicuro di come farlo [converti un puntatore a un riferimento]" - mentre non devi farlo qui, in generale lo fai facendo de-referenziare il risultato di ottenere . Ad esempio: *(get()).

Secondo, errore del compilatore.L'errore deriva dal fatto che c'è un conflitto:

a) get() restituisce un const Foo *

b), ma set memorizza un Foo* - non un const Foo *, così insert accetta solo un mutevole Foo

Così si può memorizza un puntatore costante all'interno del tuo QSet<Foo*>. Questo ha senso perché è possibile utilizzare set per accedere e modificare i Foo s al suo interno, cosa che si promette di non fare con uno const Foo.

Questo riferimento dovrebbe essere utile:

https://isocpp.org/wiki/faq/const-correctness

Si può anche pensare se si può semplicemente utilizzare un QSet<Foo> invece di un QSet<Foo*>. Nel primo caso, le cose si comporteranno probabilmente come ci si aspetta.

+1

Guardando https://isocpp.org/wiki/faq/const-correctness#const-ref-alt, è vero che 'const X *' è equivalente a 'X const *' per costrutti di tipo arbitrariamente 'X' ? –

+0

È quando 'X' è un tipo - non è se' X' è più complicato .. In effetti, è per questo che ho dovuto fare esattamente quello scambio prima di sostituire in 'T'. Scrivendolo 'X const *' rende più facile leggere da destra a sinistra ("un puntatore a una costante' X'). Ma scriverlo 'const X *' rende più evidente nel codice sorgente che il tipo è "a costante 'X'". Quindi di solito si vede 'const X *' nel codice. – Corey

+0

Per i modelli potrebbe essere confuso, quindi ... Chiunque abbia scritto 'QSet' potrebbe avere codificato' insert (const T & value) 'o' insert (T const & value) 'e sarebbero stati gli stessi, ma questo è dovuto al fatto che il compilatore sa cosa fare.Se ** vuoi ** sostituire" T "su carta o nella tua testa, tu ** deve ** pensarlo come 'insert (T const & value)' prima di fare la sostituzione – Corey

5

si sta cercando di prendere un const Foo * e inserirla in un QSet<Foo *>, ma il compilatore non convertirà automaticamente un const Foo * ad una pianura Foo * al fine di farlo.

+1

@Jefffrey: Poiché il 'QSet ' contiene puntatori non const. Non è possibile modificare un puntatore-a-const in un puntatore-a-non-implicitamente. –

3

ho risolto il problema cambiando il tipo di fascicolo nell'ordine seguente.

QSet<Foo const*> set; 

Con questa modifica, la compilazione ha esito positivo.

3

sei violare il const-ness del puntatore restituito dalla vostra funzione get(). get() restituisce un puntatore a un oggetto const di tipo Foo, ma successivamente si tenta di inserirlo in un vettore di puntatori non-const . È necessario const_cast il valore restituito da get() o modificare il tipo di ritorno di get() da const Foo* ad appena Foo*.

+0

Queste sarebbero state le altre due alternative. –

Problemi correlati