Question

Je donne sur ce ...

  

5.2.7 / 2 $ « Si T est un type de pointeur, v   doit être un rvalue d'un pointeur vers   type de classe complète, et le résultat est   un rvalue de type T. Si T est   type de référence, v est une lvalue   d'un type de classe complète, et   Il en résulte une lvalue du type   appelé par T. "

Conformément à ce qui précède, le code suivant doit être bien formé.

struct A{};
struct B : A{};

int main(){
   B b;
   A a, &ar1 = b;

   B& rb1 = dynamic_cast<B&>(ar1);  // Does not $5.2.7/2 apply here?
   B& rb2 = dynamic_cast<B&>(a);    // and also here?
}

Mais ce n'est pas. Tous les compilateurs se plaignent de l'opérande à dynamic_cast ne pas être polymorphes conformément à

  

5.2.7 / 6 $ Dans le cas contraire, v est un   pointeur vers un ou d'un lvalue   type polymorphe (10.3).

Alors, ma question est qu'est-ce que 5.2.7 / 2 $ signifie? Pourquoi 5.2.7 / 6 $ coup ici?

Était-ce utile?

La solution

"Sinon" signifie dans ce cas, "à moins que les conditions 5.2.7 / 5 appliquer".

Vous pouvez dire cela parce que / 2 places une exigence sur le programme en ce qui concerne l'opérande de la dynamic_cast (notez le « shall » de la langue « v est une lvalue » par rapport à la langue « est » de « le résultat est lvalue "). En commun avec d'autres endroits dans la norme, l'expression d'une exigence ne signifie pas nécessairement que c'est le uniquement exigence. D'autres clauses peuvent énoncer des exigences supplémentaires. Dans ce cas, / 6 états d'une exigence supplémentaire applicable que dans certains cas, en fonction de T et le type statique de v.

/ 3, / 4, / 5 vous disent au sujet de la valeur du résultat, et ils sont tout à fait conforme à l'exigence / 2. Aucun d'entre eux commence par « Dans le cas contraire ». Donc, pour moi, il est assez évident qu'ils ne forment pas un « autre si » la chaîne à partir de / 2.

Certains supports ou quelque chose pourrait rendre plus clair (à savoir que les "autrement" in / 6 applique au "if" in / 5, et non à la "if" in / 2, / 3 ou / 4). Mais c'est tout simplement pas le style de la maison.

En dehors de toute autre chose, la « autrement » / 5 appliquer peut logiquement pas de manière significative aux conditions / 2. / 1 dit que T doit être "pointeur ou référence pour compléter le type de classe, ou cv void*". / 2 couvre deux cas - types de pointeur et les types de référence. C'est tout. Il n'y a pas « autrement » à / 2 (sauf à dire « autrement, un compilateur conforme doit émettre un diagnostic », mais qui est implicite)

Autres conseils

Eh bien, respecter toutes les exigences 5.2.7 ensemble . Vous ne pouvez pas arrêter après 5.2.7 / 2 et commencer à écrire du code qui satisfait soi-disant tout « jusqu'à 5.2.7 / 2 ». L'ensemble 5.2.7 définit la spécification de dynamic_cast.

L'exigence est polymorphique distingué parce qu'il est condition . Lorsque vous utilisez dynamic_cast pour upcasts, l'exigence polymorphes ne s'applique pas (en fait, dynamic_cast équivaut à static_cast à upcasts). L'exigence polymorphes applique uniquement lorsque vous utilisez dynamic_cast pour downcasts ou crosscasts.

La spécification de dynamic_cast est organisée de façon séquentielle, ce qui signifie qu'elle prend en charge des cas simples d'abord, et procède ensuite à des applications plus complexes. Vous êtes censé le lire, étape par étape, jusqu'à ce qu'elle couvre votre situation particulière. Tout ce que vous lisez sur ce chemin applique de façon cumulative, et « autrement » signifie:. « Si nous n'avons pas encore couvert votre cas, puis continuer à lire »

Pour faire un baissés comme dans votre exemple, struct A doit être polymorphes, et ont RTTI. Voici une version adaptée qui fonctionne, à un point:

struct A{virtual void f(){}};
struct B : A{};

int main(){
   B b;
   A a, &ar1 = b;

   B& rb1 = dynamic_cast<B&>(ar1);  // Does not $5.2.7/2 apply here?
   //B& rb2 = dynamic_cast<B&>(a);    // and also here?
}

En ajoutant une prise virtuelle il polymorphes, RTTI est activé pour la classe, ce qui permet downcasts.

Notez que votre deuxième exemple ne peut pas fonctionner - puisque vous Jetant un pod (a) à une référence à une nacelle -. Ce qui est interdit


Mise à jour:

Votre code n'est pas autorisé sous 5.2.7.5 et est ni autorisé sous 5.2.7.6. Mon réglage fait fonctionner sous 5.2.7.6

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top