Je viens de trouver les paragraphes suivants dans le projet de norme C++ 03 concernant la conversion de pointeur en membre.Conversion de pointeur en membre
4,11/2 Pointeur sur les conversions membres
Un rvalue de type « pointeur vers un membre de B de type cv T », où B est un type de classe, peut être converti en un rvalue de type "Pointeur sur un membre de D de type cv T", où D est une classe dérivée (clause 10) de B. Si B est une classe de base inaccessible (article 11), ambiguë (10.2) ou virtuelle (10.1) de D, un programme qui nécessite cette conversion est mal formé. Le résultat de la conversion fait référence au même membre que le pointeur vers le membre avant la conversion, mais il fait référence au membre de la classe de base comme s'il s'agissait d'un membre de la classe dérivée . Le résultat se réfère au membre dans l'instance de D de B. Puisque le résultat a un type "pointeur vers le membre de D de type cv T", il peut être déréférencé avec un objet D. Le résultat est le même que si le pointeur à un membre de B ont été déréférencé avec le sous-objet B de D. La valeur du pointeur d'élément nul est converti en la valeur du pointeur d'élément nul de la type.52 de destination)
5.2.9/9 static_cast
un rvalue de type « pointeur vers un membre de D de type CV1 T » peut être converti en un rvalue de type « pointeur vers un membre de B de type CV2 T », où B est une classe de base (clause 10) de D, si une conversion standard valide de "pointeur en membre de B de type T" en "pointeur en membre de D de type T" existe (4.11), et cv2 est le même cv -qualification en tant que, ou une plus grande cv-qualification que, cv1.63) La valeur de pointeur de membre null (4.11) est convertie en la valeur de pointeur de membre null du type de destination. Si la classe B contient le membre d'origine ou est une base ou une classe dérivée de la classe contenant le membre d'origine, le pointeur vers le membre d'origine pointe vers le membre d'origine. Sinon, le résultat de la distribution est indéfini. [Note: bien que la classe B ait besoin de ne contienne pas le membre original, le type dynamique de l'objet sur lequel le pointeur vers le membre est déréférencé doit contenir le membre original; voir 5.5. ]
Alors, voici ma question. Comme le dit le 5.2.9/9, un pointeur vers un membre de D peut être converti en un pointeur vers un membre de B, s'il existe une conversion valide décrite en 4.11/2. Est-ce que cela signifie que s'il y a un membre 'm' de D qui n'est pas hérité de B, le pointeur sur le membre 'm' ne peut pas être converti en type de pointeur en membre de B?
class Base { };
class Derived : public Base
{
int a;
};
typedef int Base::* BaseMemPtr;
BaseMemPtr pa = static_cast<BaseMemPtr>(&Derived::a); // invalid, as per 5.2.9/9 ?
Dans la note 5.2.9/9, il est dit aussi que, bien que ne doit pas contenir la classe B du membre d'origine, le type dynamique de l'objet sur lequel le pointeur de membre est déréférencé doit contenir le membre d'origine .
Je suis confus avec le libellé du paragraphe. Le code ci-dessus est-il valide?
J'ai recherché le site, et il y a une question similaire, c++ inheritance and member function pointers, dont la réponse ne couvrait que le cas où la conversion de pointeur en membre de classe de base en pointeur en membre de classe dérivée.
Vous affectez un pointeur à la valeur du membre de données à un pointeur sur la variable de fonction membre. Sinon, oui, "le résultat de la distribution est indéfini". – Potatoswatter
Merci, je l'ai réparé. – ashen