11
votes

Const_cast toujours utile?

Récemment, j'ai trouvé un morceau de code C ++ qui effectue efficacement les éléments suivants: xxx

évidemment, l'auteur pensait que const_cast signifie "ajouter le const", mais en fait const peut être aussi bien ajouté implicitement: xxx

y a-t-il de cas lorsque je devrais vraiment const_cast < em> to un pointeur-to-const ( const_cast comme dans l'exemple ci-dessus)?


6 commentaires

Un seul à laquelle je peux penser est de forcer un type spécifique pour l'instanciation de modèles - ou pour la résolution de la surcharge.


Une ride intéressante, même si je ne vois pas pourquoi cela rendrait la construction plus utile, c'est que vous pouvez utiliser const_cast pour ajouter ou soustraire volatile ainsi que Const .


Je me demande aussi comment il diffère de static_cast


@Omnifarious: En effet, et c'est pourquoi pas utiliser const_cast pour ajouter const . L'ensemble des conversions restreintes en C ++ est de sorte que vous pouvez utiliser celui qui le fait aussi peu que possible, y compris ce que vous voulez. Je me demande s'il serait utile d'écrire un modèle implict_cast qui vous permet de signaler au code qu'une conversion se déroule, mais assurez-vous que seules les conversions implicites sont effectuées. Par conséquent, vous ne supprimerez pas accidentellement volatile (comme avec const_cast à un type de pointeur) ou utilisez un constructeur explicite (comme avec static_cast à une classe taper).


@StactedCooked: lorsque la cible est Const Char * , je pense que la seule différence est que const_cast peut supprimer volatile et statique_cast ne peut pas. Pour les indicateurs des types de classes, cependant, const_cast ne doit pas être arrêté ni (encore plus crucial) bowncast et static_cast sera. Fondamentalement, ils ont différentes manières de faire accidentellement quelque chose que vous ne vouliez pas dire lorsque le type de source n'est pas tout à fait ce que vous pensiez.


Cette discussion me fait me demander, ce qui ne serait pas un meilleur moyen d'ajouter explicitement la consensité: modèle const t & const_ref (const t & t) {retour t; } ? Cela ne toucherait pas la volatilité, ni n'essayerait de jeter l'objet à un type différent (tant que vous laissez la déduction du type de modèle, cela fonctionne normalement).


4 Réponses :


5
votes

Peut-être pour forcer la résolution de la surcharge dans les cas où vous avez F (t *) et f (const t *).


3 commentaires

Bien que si ces deux fonctions font quelque chose de distinct, leur auteur devrait probablement être giflé quelques fois.


@ EDA-QA Mort-ORA-Y: La copie de l'entrée dans un objet de données temporaire compte-t-elle comme quelque chose de distinct?


Par distinct, je veux dire le retour / effet de la fonction. Il est parfaitement raisonnablement de les mettre en œuvre différemment, mais les deux formes doivent avoir le même résultat ultime. C'est-à-dire que cela n'aurait pas d'importance que l'on appelle, le sens de haut niveau du programme ne devrait pas changer.



3
votes

Vous pouvez utiliser static_cast code> pour ajouter le const aussi. Donc, je ne vois aucune situation où vous dois em> utiliser const_cast code> pour ajouter const code>. Mais casting explicite (que ce soit l'un ou l'autre) peut parfois être nécessaire lorsque vous souhaitez modifier le type de l'objet par exemple pour la résolution de surcharge.

E.g. P>

void f(char*);
void f(const char*);

int main()
{
   char* p = 0;
   f(p); //calls f(char*)
   f(static_cast<const char*>(p)); //calls f(const char*);
   f(const_cast<const char*>(p)); //calls f(const char*);
}


10 commentaires

statc_cast est dangereux à utiliser si tout ce que vous voulez faire est d'ajouter const .


@Armen Tsirunyan: Parce que si une personne modifie le type de variable que vous moulez, la distribution pourrait bien le jeter à un type aléatoire et sans rapport sans raison apparente. Il rend le code plus difficile à maintenir.


@Omnifarious: Je suis désolé mais cela n'a aucun sens. Dans la même logique, le type a pu être modifié pour ajouter un deuxième const, et le const_cast le supprimerait ...


Supposons que lorsque vous écrivez votre code d'abord, la variable est de type dérivé * . Et vous static_cast (v) . Ensuite, plus tard, une personne change le type de variable à base * . Oups, le static_cast est toujours aveuglément le casser s'il est ou non valide. Un const_cast provoquerait une erreur de compilateur.


@Omnifarious: OK, vous m'avez un peu convaincu :)


@Armen Tsirunyan: Vous avez raison, cela pourrait arriver. Mais c'est un type d'erreur plus spécifique que si vous aviez static_cast . Le nombre de types possibles que vous pouvez modifier la variable pour être qui entraînerait un problème est beaucoup plus élevé avec static_cast que const_cast .


@Omnifarious: Pourquoi ne résumez-vous pas votre idée dans une bonne réponse que je voudrais volontiers upvote?


@Armen: Non, je suis d'accord avec Omnifarious. Il est évident de voir qu'il écrit explicitement le type de base de la variable à nouveau crée un point de défaillance potentiel inutile.


@Tomalak: Comme vous pouvez le constater, je suis d'accord avec lui aussi


@Armen: Votre conversation déroule trop vite pour moi: p



6
votes

const_cast , malgré son nom, n'est pas spécifique au const ; Il fonctionne avec cv-qualificiers qui comprend efficacement les deux const et volatile .

Lorsque l'ajout d'un tel qualificatif est autorisé de manière transparente, en supprimant de manière transparente. un const_cast .

Par conséquent, dans l'exemple que vous donnez: xxx

la présence du const_cast est faux (je pense personnellement qu'il obscurcisse la syntaxe).

mais vous pouvez souhaiter supprimer volatile , auquel cas vous aurez besoin: < Pré> xxx

Ceci pourrait apparaître, par exemple, dans le code du pilote.


0 commentaires

10
votes

où vous avez 2 surcharges et que vous souhaitez forcer le const à être exécuté. C'est souvent le cas lorsque vous appelez un en termes d'autre.

B* A::get()
{
    const A* constthis = this; // no need to cast
    return const_cast<B*>(constthis->get());
}


5 commentaires

Vous pouvez éviter de taper un const_cast <> en faisant l'inverse: Mise en œuvre d'une fonction de membre Const en termes d'un non constitué. C'est parce que la conversion t * sur t const * ne nécessite pas de couler explicite.


@MAXIMYEGORUSKINKIN: qui ouvrira la porte à Terrain de comportement non défini ! Désolé pour le commentaire tardif, mais je pense que cet avertissement est important.


@ Matthäusbrandl lorsqu'un objet est non-const, le casser à Const et en arrière est bien défini.


Peut-être que j'ai lu votre commentaire faux? Mise en œuvre de la fonction Const en termes de non- Const On sonne comme la création de cette 'Constance d'appeler le membre non-Const, puis de renvoyer le résultat à la const.


Stackoverflow.com/Questtions/123758/...