2010-02-26 20 views
7

Je ne sais pas comment exprimer la question très bien dans une courte ligne de sujet, alors laissez-moi essayer une explication plus longue. Supposons que j'ai ces classes d'exception:Pouvez-vous attraper une exception par le type d'un opérateur de conversion?

class ExceptionTypeA : public std::runtime_error 
{ 
    // stuff 
}; 

class ExceptionTypeB : public std::runtime_error 
{ 
    // stuff 

    operator ExceptionTypeA() const; // conversion operator to ExceptionTypeA 
}; 

Puis-je faire cela, et le faire déclencher le bloc catch?

try 
{ 
    throw ExceptionTypeB(); 
} 
catch (ExceptionTypeA& a) 
{ 
    // will this be triggered? 
} 

Je vais deviner que ce ne sera pas, ce qui est regrettable, mais je pensais que je demande, puisque je ne pouvais trouver aucune information à ce sujet sur le net ou sur le SO. Et oui, je me rends compte que je pourrais simplement exécuter le programme dans mon compilateur et voir ce qui se passe, mais cela ne me dirait pas ce que la norme dit de ce comportement, juste ce que mon compilateur implémente (et je ne lui fais pas confiance).

Répondre

13

Vous ne pouvez pas. Standardese à 15.3/3:

Un gestionnaire est une correspondance pour un objet d'exception de type E si

  • Le gestionnaire est de type cv T ou cv T& et E et T sont du même type (en ignorant les feuilles supérieure cv- niveau qualificatifs) ou
  • le gestionnaire est de type cv T ou cv T& et T est une classe de base publique non ambiguë de E, ou
  • le gestionnaire est de type cv1 T* cv2 et E est un type de pointeur qui peut être converti en le type du gestionnaire par l'un ou les deux
    • une conversion de pointeur standard (4.10) ne comportant pas les conversions à des pointeurs vers des privés ou protégés ou des classes ambiguës
    • une conversion de qualification

Votre scénario souhaité correspond à aucun de ceux-ci. cv signifie "combinaison const et/ou volatile"

+1

Oeuf. Un soupir de soulagement ici. – sbi

+0

cela couvre-t-il les membres? par exemple, le pointeur vers les données membres est contravariant, donc 'int (Base :: *)' peut être converti en 'int (Derived :: *)'. puis-je attraper ce dernier si je lance le premier? gcc semble être en désaccord, mais le libellé standard est un peu flou. – max