C Nom du membre de la classe des problèmes de consultation (en ce qui concerne le libellé de la norme N3225)

StackOverflow https://stackoverflow.com/questions/4742737

  •  13-10-2019
  •  | 
  •  

Question

Je suis très confus au sujet de la norme 10.2 / 13,

  

[Note: Même si le résultat de la recherche de nom est sans ambiguïté, l'utilisation d'un nom trouvé dans plusieurs sous-objets peut encore être ambigu (4.11, 5.2.5, 5.3.1, 11.2) .- Note de fin] [Exemple:

struct B1 {
  void f();
  static void f(int);
  int i;
};
struct B2 {
  void f(double);
};
struct I1: B1 { };
struct I2: B1 { };
struct D: I1, I2, B2 {
  using B1::f;
  using B2::f;
  void g() {
    f(); // Ambiguous conversion of this
    f(0); // Unambiguous (static)
    f(0.0); // Unambiguous (only one B2)
    int B1::* mpB1 = &D::i; // Unambiguous
    int D::* mpD = &D::i; // Ambiguous conversion
  }
};

Je ne vois pas pourquoi cela est sans ambiguïté int B1 :: * MPB1 = & D :: i; // non ambiguë

Visual C ++, gcc et Clang disent tous qu'il est accès ambigu à D :: i!

Le libellé semble être lié à la question de base # 39 http://www.open-std.org/jtc1 /sc22/wg21/docs/cwg_defects.html#39 , et la proposition finale est ici: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1626.pdf

Je trouve maintenant que les nouvelles formulations à base d'algorithmes (10.2 / 3 à 10,2 / 6) sont encore plus confuse, car aucun de la note 10.2 / 9, 10.2 / 10, 10,2 / 11 et 10,2 / 13 entièrement conforme à 10,2 / 3 à 10,2 / 6. Je peux prendre 10.2 / 9-10.2 / 11 comme des exceptions, mais je suis particulièrement confus au sujet de 10.2 / 13. Je ne sais pas sur l'intention de 10.2 / 13.

Comment l'exemple 10.2 / 13 être regardé en place selon le 10.2 / 3 à 10,2 / 6? Quel est l'intention de 10.2 / 13, à savoir, quelle est la situation 10.2 / 13 est considéré comme une exception de 10,2 / 3 à 10,2 / 6?

S'il vous plaît me donner quelques conseils. Merci beaucoup.


Après quelques réflexions, je pense que l'intention de 10.2 / 13 est plus clair pour moi.

int B1 :: * MPB1 = & D :: i; // non ambiguë

Cela devrait être sans ambiguïté et les compilateurs actuels ont tort sur ce point. Ceci est sans ambiguïté, car pointeur à l'initialisation des membres de la classe ne comporte pas encore accès à l'objet.

int D :: * mpd = & D :: i; // conversion Ambigu

en fait des moyens quand converti à partir int B1 :: * MPB1 à D :: int * mpd, la conversion est ambiguë en raison des classes de base ambiguës.

Était-ce utile?

La solution

int B1::* mpB1 = &D::i; // Unambiguous

est sans ambiguïté parce que le résultat est affecté à un pointer to member de classe B.
Ainsi, il n'a pas d'importance qui i est choisi comme le décalage est relatif à un élément de B (et non la classe D-mère).

Il est donc sans ambiguïté à vous et moi, mais je ne pense pas que le compilateur peut gérer.

Autres conseils

Pour la B1 :: * cas, l'interprétation est sans ambiguïté, étant simplement le décalage par rapport au début de B1 à i.

5.3.1 / 3:

struct A { int i; };
struct B : A { };
... &B::i ... // has type int A::*

Donc, l'astuce est de faire & D :: i être de type B1 :: * en premier lieu. Puis:

int B1::* mpB1 = &D::i; // Unambiguous

est simple. L'intérêt est alors en:

int D::* mpD = &D::i; // Ambiguous conversion

Ici, l'ERS est de type B1 :: * et a besoin d'une conversion que nous devons déterminer quelle base est fait référence.

Une vérification rapide sur ISO IEC 14882 2003 L'article 10 n'a pas cet exemple, ou quelque chose de semblable à cela. C ++ 0x est projet standard et VC ++ / GCC / Clang ne sont pas conformes à elle.

Je pense: Ceci est un sous-produit de la nouvelle frappe de auto et ne se trouve pas dans la norme C ++ plus de.

FWIW, je copie sur ma réponse que je donnais à la copie usenet de cette question:

  

Salut à tous,
  
  Je suis très confus au sujet de la norme N3225 10.2 / 13,   
  [Note: Même si le résultat de la recherche de nom est sans ambiguïté, l'utilisation d'un   nom trouvé dans plusieurs sous-objets pourrait encore être ambigu (4,11,   5.2.5, 5.3.1, 11.2) .- Note de fin] [Exemple:   

struct B1 {
  void f();
  static void f(int);
  int i;
};
struct B2 {
  void f(double);
};
struct I1: B1 { };
struct I2: B1 { };
struct D: I1, I2, B2 {
  using B1::f;
  using B2::f;
  void g() {
    f(); // Ambiguous conversion of this
    f(0); // Unambiguous (static)
    f(0.0); // Unambiguous (only one B2)
    int B1::* mpB1 = &D::i; // Unambiguous
    int D::* mpD = &D::i; // Ambiguous conversion
  }
};
  

Je ne vois pas pourquoi cela est sans ambiguïté int B1 :: * MPB1 = & D :: i; //   Non ambigu   

&D::i est de type int B1::*, et se réfère sans ambiguïté à l'élément de données de i B1. Si vous déréférencer avec un objet ou D si vous attribuez à un int  D::*, vous obtiendrez une ambiguïté au besoin.

  

Visual C ++, gcc et Clang disent tous qu'il est accès ambigu à D :: i!   

Aucun de ces compilateurs mettre en œuvre encore 10.2.

  

Le libellé semble être lié à la question de base # 39    http://www.open-std.org/jtc1 /sc22/wg21/docs/cwg_defects.html#39 , et   la proposition finale est ici:    http://www.open-std.org /jtc1/sc22/wg21/docs/papers/2004/n1626.pdf      Je trouve maintenant que les nouvelles formulations à base d'algorithmes (10.2 / 3 à 10,2 / 6) sont   encore plus déroutant, car aucun de la note 10.2 / 9, 10.2 / 10,   10,2 / 11 et 10,2 / 13 se conforme entièrement à 10,2 / 3 à 10,2 / 6. je peux prendre   10.2 / 9-10.2 / 11 comme des exceptions, mais je suis particulièrement confus au sujet de   10.2 / 13. Je ne sais pas sur l'intention de 10.2 / 13.   

Vous devez donner des exemples qui montrent ce que vous ne comprenez pas.

  

Comment l'exemple 10.2 / 13 être recherchée en fonction du   10.2 / 3 à 10,2 / 6? Quel est l'intention de 10.2 / 13, à savoir, quelle est la   situation dont 10.2 / 13 est considéré comme une exception   10.2 / 3 à 10,2 / 6?   

Le nouvel algorithme fondé sur des règles recherche découple problèmes d'exécution (trouver un objet unique) de compilation / préoccupations Lookup (la recherche d'une déclaration un nom fait référence).

Ce qui suit est bien formé avec le nouveau libellé:

struct Z { int z; };
struct X : Z { };
struct Y : Z { };
struct A : X, Y { };

struct B : A {
  using A::z;
};

La déclaration using A::x; introduit un nom de membre en B qui fait référence à la déclaration Z::z. Dans un contexte déclarative, cela est parfaitement bien. Un l'erreur est levée uniquement lorsque vous accédez B::z comme une expression d'accès membre (5.2.5).

Ne vous sentez pas mal d'avoir confondu ce cas sur le pointeur de membre. je l'ai fait trop dans le passé, et correspondant rapport d'émission en fait en un C + + projet de 0x. Ils heureusement changé arrière quand ils ont remarqué que le changement a eu tort.

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