Cos'è const void?


89

La descrizione di std::is_voidafferma che:

Fornisce il valore della costante del membro che è uguale a true, se T è il tipo void, const void, volatile void o const volatile void.

Allora cosa potrebbe essere const void, o un volatile void?

Questa risposta afferma che il const voidtipo restituito non sarebbe valido (tuttavia viene compilato su VC ++ 2015)

const void foo() { }

Se per standard, const voidnon è valido (VC è sbagliato), allora cos'è const void?


15
La risposta a cui ti colleghi non afferma che sarebbe non valida, afferma che sarebbe "priva di significato", il che significherei "non offre alcun vantaggio voidsenza const".

@ hvd, la risposta afferma che il compilatore dovrebbe avvisare / errore su tale qualifica. Con ciò presumo che lo standard C ++ non consenta qualifiche convoid
Ajay

2
La risposta afferma che il compilatore dovrebbe avvertire di tale qualifica, non menziona un errore e un errore sarebbe sbagliato. Quell'osservazione riguarda solo la qualità dell'attuazione, non la conformità, ma posso capire che non è affatto chiaro dall'osservazione stessa.

@Ajay lo standard non specifica che dovrebbe essere visualizzato un avviso quando si utilizza un codice privo di significato. È stata una decisione di gcc darti un ulteriore suggerimento che questo codice non fa nulla. Ma VC non ha torto in alcun modo.
user1942027

3
@Ajay La risposta afferma che clang dà un avvertimento e che, secondo l'opinione dell'autore, altri compilatori dovrebbero farlo. Se lo standard non lo consentisse, sarebbe un errore, non un avvertimento.
molbdnilo

Risposte:


94

const voidè un tipo a cui puoi formare un puntatore. È simile a un normale puntatore void, ma le conversioni funzionano in modo diverso. Ad esempio, a const int*non può essere convertito implicitamente in a void*, ma può essere convertito implicitamente in a const void*. Allo stesso modo, se hai un const void*non puoi static_castfarlo con un int*, ma puoi static_castfarlo con un const int*.

const int i = 10;
void* vp = &i;                           // error
const void* cvp = &i;                    // ok
auto ip = static_cast<int*>(cvp);        // error
auto cip = static_cast<const int*>(cvp); // ok

4
Sebbene la tua risposta sia buona, non indica il motivo di const void, ma è tutto intorno a puntatori vuoti e non vuoti [con (non) costanza].
Ajay

26
@ Ajay: non sono d'accordo. A const void*è l'unica ragione per cui vedresti mai const void. Potrebbe essere passato come argomento del modello, ma quel tipo di argomento verrà istanziato solo con un *alla fine.
Benjamin Lindley

@BenjaminLindley Potresti anche vedere const voidnella domanda posta dall'avvocato della lingua
cpplearner

3
@Ajay: Ad un certo punto questa domanda diventa una questione di filosofia. La "ragione" di const voidè che tutti i tipi in C ++ possono essere creati const. "Esiste" nello stesso modo in cui voidesiste. La risposta di @Benjamin Lindley spiega di cosa si tratta quando lo vedi e come lo usi.
Chris Beck

23

As void, const voidè un tipo vuoto. Tuttavia, se const voidè un tipo restituito , non ha constsenso (anche se legale!), Perché [expr] / 6 :

Se un prvalue ha inizialmente il tipo " cv T ", dove Tè un tipo cv non qualificato non di classe, non di matrice, il tipo di espressione viene adattato Tprima di qualsiasi ulteriore analisi.

Tuttavia, è di per sé un tipo valido e si trova, ad esempio, nelle funzioni di libreria standard C , dove viene utilizzato per garantire la correttezza const dei puntatori agli argomenti: int const*non può essere convertito in void*, ma void const*.


const voidpoiché un tipo restituito influisce sul tipo di funzione, quindi non è completamente privo di significato.
cpplearner

1
@cpplearner Tranne che è in ogni senso pratico, perché né la firma della funzione né il tipo di una chiamata ad essa sono influenzati.
Columbo

Bene, può cambiare la firma di un modello di funzione. +1 comunque
cpplearner

@cpplearner Abbastanza giusto, tuttavia è ancora uno spreco di tasti.
Columbo

Normalmente vediamo: const int * non può andare a void *, ma const void *.
mgouin

18

I tipi possono essere il risultato di modelli; un modello potrebbe indicare const Ted essere istanziato con Tas void.

La risposta collegata è fuorviata, o meglio, limitata in quanto riguarda il caso speciale di un tipo non modello, e anche in questo caso const voidpotrebbe essere priva di significato , ma è codice valido .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.