O que é const void?

90

A descrição dos std::is_voidestados que:

Fornece o valor da constante do membro igual a true, se T for do tipo void, const void, volatile void ou const volatile void.

Então o que poderia ser const void, ou um volatile void?

Esta resposta afirma que o const voidtipo de retorno seria inválido (no entanto, compila em VC ++ 2015)

const void foo() { }

Se, por padrão, const voidfor inválido (VC estando errado) - então o que é const void?

Ajay
fonte
15
A resposta para a qual você vincula não afirma que seria inválida, ela afirma que seria "sem sentido", o que eu interpretaria como "não oferece nenhum benefício voidsem const".
@hvd, a resposta afirma que o compilador deve avisar / errar sobre tal qualificação. Por isso, presumo que o padrão C ++ não permite qualificações comvoid
Ajay
2
A resposta afirma que o compilador deve avisar sobre tal qualificação, não menciona um erro e um erro seria errado. Essa observação é apenas sobre a qualidade da implementação, não sobre conformidade, mas posso entender que isso não está totalmente claro na observação em si.
@Ajay o padrão não especifica que deve haver um aviso quando você usa código sem sentido. Foi uma decisão do gcc dar a você uma dica adicional de que esse código não faz nada. Mas o VC não está errado de forma alguma.
user1942027
3
@Ajay A resposta afirma que o clang é um aviso e que, na opinião do autor, outros compiladores deveriam. Se o padrão não permitisse, seria um erro, não um aviso.
molbdnilo

Respostas:

94

const voidé um tipo para o qual você pode formar um ponteiro. É semelhante a um ponteiro void normal, mas as conversões funcionam de maneira diferente. Por exemplo, a const int*não pode ser convertido implicitamente em a void*, mas pode ser convertido implicitamente em a const void*. Da mesma forma, se você tem um const void*que você não pode static_cast-lo para um int*, mas você pode static_cast-lo para um 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
Benjamin Lindley
fonte
4
Embora sua resposta seja boa, ela não indica o motivo de const void, mas tudo em torno de ponteiros vazios e não vazios [com (não) constância].
Ajay
26
@Ajay: Eu discordo. A const void*é a única razão que você veria const void. Pode ser passado como um argumento de modelo, mas esse tipo de argumento só será instanciado com um *no final dele.
Benjamin Lindley
@BenjaminLindley Você também pode ver const voidna pergunta feita pelo advogado linguagem
cpplearner
3
@Ajay: Em algum momento essa questão se torna uma questão de filosofia. O "motivo" const voiddisso é que todos os tipos em C ++ podem ser criados const. Ele "existe" da mesma maneira que voidexiste. A resposta de @Benjamin Lindley explica o que é quando você o vê e como o usa.
Chris Beck de
23

As void, const voidé um tipo vazio. No entanto, se const voidfor um tipo de retorno , o constnão faz sentido (embora seja legal!), Porque [expr] / 6 :

Se um prvalue tiver inicialmente o tipo “ cv T ”, onde Té um tipo cv não qualificado, não classe e não array, o tipo da expressão é ajustado Tantes de qualquer análise posterior.

No entanto, é um tipo válido em si mesmo e ocorre em, por exemplo , funções de biblioteca padrão C , onde é usado para garantir exatidão constante de ponteiros de argumento: int const*não pode ser convertido para void*, mas void const*.

Columbo
fonte
const voidcomo um tipo de retorno afeta o tipo de função, portanto, não é completamente sem sentido.
cpplearner de
1
@cpplearner Exceto que é em todos os sentidos práticos, porque nem a assinatura da função nem o tipo de uma chamada para ela são afetados.
Columbo
Bem, ele pode alterar a assinatura de um modelo de função. +1 no entanto
cpplearner
@cpplearner É justo - ainda é um desperdício de teclas, no entanto.
Columbo
Normalmente vemos: const int * não pode ir para void *, mas const void *.
mgouin
18

Os tipos podem ser o resultado de modelos; um modelo pode indicar const Te ser instanciado com Tcomo void.

A resposta vinculada é enganada, ou melhor, limitada, visto que se refere ao caso especial de um tipo não modelo e, mesmo assim, const voidpode não ter sentido , mas é um código válido .

DevSolar
fonte