Qu'est-ce que const void?

89

La description de std::is_voidindique que:

Fournit la valeur de constante de membre égale à true, si T est du type void, const void, volatile void ou const volatile void.

Alors que pourrait être const void, ou un volatile void?

Cette réponse indique que le const voidtype de retour serait invalide (cependant compile sur VC ++ 2015)

const void foo() { }

Si par norme, const voidest invalide (VC étant faux) - alors qu'est-ce que c'est const void?

Ajay
la source
15
La réponse à laquelle vous établissez un lien n'indique pas qu'elle serait invalide, elle déclare qu'elle serait "dénuée de sens", ce que je considérerais comme "n'offre aucun avantage voidsans const".
@hvd, la réponse indique que le compilateur doit avertir / erreur concernant une telle qualification. Par cela, je suppose que la norme C ++ ne permet pas les qualifications avecvoid
Ajay
2
La réponse indique que le compilateur doit avertir d'une telle qualification, il ne mentionne pas d'erreur et une erreur serait erronée. Cette remarque concerne simplement la qualité de la mise en œuvre, pas la conformité, mais je peux comprendre que ce n'est pas du tout clair d'après la remarque elle-même.
@Ajay le standard ne spécifie pas qu'il devrait y avoir un avertissement lorsque vous utilisez du code sans signification. C'était une décision de gcc de vous donner un indice supplémentaire que ce code ne fait rien. Mais VC ne se trompe en aucun cas.
user1942027
3
@Ajay La réponse indique que clang donne un avertissement, et que, de l'avis de l'auteur, d'autres compilateurs devraient le faire. Si la norme ne le permettait pas, ce serait une erreur, pas un avertissement.
molbdnilo

Réponses:

94

const voidest un type sur lequel vous pouvez former un pointeur. C'est similaire à un pointeur vide normal, mais les conversions fonctionnent différemment. Par exemple, a const int*ne peut pas être implicitement converti en a void*, mais il peut être implicitement converti en a const void*. De même, si vous avez un, const void*vous ne pouvez pas static_castle faire en un int*, mais vous le pouvez static_casten 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
Benjamin Lindley
la source
4
Bien que votre réponse soit bonne, elle n'indique pas la raison de const void, mais c'est des pointeurs vides et non vides [avec (non-) const-ness].
Ajay
26
@Ajay: Je ne suis pas d'accord. A const void*est la seule raison pour laquelle vous verriez jamais const void. Il peut être passé en tant qu'argument de modèle, mais ce type d'argument ne sera instancié qu'avec un *à la fin.
Benjamin Lindley
@BenjaminLindley Vous pouvez également voir const voiden question posée par l'avocat de la langue
cpplearner
3
@Ajay: À un moment donné, cette question devient une question de philosophie. La "raison" de const voidest que tous les types en C ++ peuvent être créés const. Il "existe" de la même manière qui voidexiste. La réponse de @Benjamin Lindley explique ce que c'est quand vous le voyez et comment vous l'utilisez.
Chris Beck
23

As void, const voidest un type vide. Cependant, si const voidest un type de retour , le constn'a pas de sens (bien que légal!), Car [expr] / 6 :

Si une prvalue a initialement le type « cv T », où Test un type non-classe et non tableau non qualifié cv, le type de l'expression est ajusté Tavant toute analyse ultérieure.

Cependant, c'est un type valide lui-même et se produit par exemple dans les fonctions de bibliothèque C-standard , où il est utilisé pour assurer la const-exactitude des pointeurs d'argument: int const*ne peut pas être converti en void*, mais void const*.

Columbo
la source
const voidcomme un type de retour affecte le type de fonction, il n'est donc pas complètement dénué de sens.
cpplearner
1
@cpplearner Sauf que c'est dans tous les sens pratiques, car ni la signature de la fonction ni le type d'appel à celle-ci ne sont affectés.
Columbo le
Eh bien, cela peut changer la signature d'un modèle de fonction. +1 néanmoins
cpplearner
@cpplearner Très bien - c'est toujours un gaspillage de frappes, cependant.
Columbo le
Nous voyons normalement: const int * ne peut pas aller à void *, mais const void *.
mgouin
18

Les types peuvent être le résultat de modèles; un modèle peut indiquer l'état const Tet être instancié avec Tas void.

La réponse liée est induite en erreur, ou plutôt limitée en ce qu'elle concerne le cas particulier d'un type non-modèle, et même dans ce cas const voidpourrait être dénuée de sens , mais il s'agit d' un code valide .

DevSolar
la source