C ++ questioni nome membro della classe di ricerca (per quanto riguarda la formulazione di standard di n3225)

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

  •  13-10-2019
  •  | 
  •  

Domanda

Sono molto confuso circa il livello 10,2 / 13,

[Nota: Anche se il risultato della ricerca del nome è univoco, l'uso di un nome trovato in più sotto-oggetti potrebbero ancora essere ambiguo (4.11, 5.2.5, 5.3.1, 11.2) .- fine nota] [Esempio:

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
  }
};

Non riesco a capire il motivo per cui questo è inequivocabile int B1 :: * mpB1 = & D :: i; // inequivocabile

Visual C ++, gcc e clang tutti dicono che è l'accesso ambiguo D :: I!

La formulazione sembra essere correlato alla questione centrale # 39 http://www.open-std.org/jtc1 /sc22/wg21/docs/cwg_defects.html#39 , e la proposta finale è qui: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1626.pdf

Ora scoprire che le nuove formulazioni a base di algoritmo (10,2 / 3-10,2 / 6) sono ancora più confuso perché nessuno di nota in 10.2 / 9, 10,2 / 10, 10.2 / 11, e 10,2 / 13 pienamente conforme a 10,2 / 3-10.2 / 6. Posso prendere 10.2 / 9-10,2 / 11 come eccezioni, ma sono particolarmente confuso circa 10,2 / 13. Non ho idea sull'intenzione di 10.2 / 13.

Come dovrebbe l'esempio 10.2 / 13 essere guardato-up a seconda del 10,2 / 3-10,2 / 6? Qual è l'intenzione di 10,2 / 13, vale a dire, qual è la situazione che 10,2 / 13 è considerato come eccezione di 10,2 / 3-10,2 / 6?

Si prega di darmi qualche suggerimento. Grazie mille.


Dopo qualche pensiero, penso che l'intenzione di 10,2 / 13 è più chiaro per me.

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

Questo dovrebbe essere univoca e compilatori attuali sono sbagliato su questo. Questo è ambigua perché puntatore ai membri della classe di inizializzazione non comporta in accede all'oggetto ancora.

int D :: * MPD = & D :: i; // conversione ambiguo

Questo significa in realtà quando convertire da int B1 :: * mpB1 a int D :: * MPD, la conversione è dovuto ambiguo classi base ambigui.

È stato utile?

Soluzione

Questa:

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

non è ambiguo perché il risultato è stato assegnato ad una pointer to member di classe B.
Quindi non importa quale i viene scelto come offset è relativo ad un membro B (non la classe genitore D).

Quindi è inequivocabile a voi e me, ma io non credo che il compilatore in grado di gestirlo.

Altri suggerimenti

Per la B1 :: * caso, l'interpretazione è univoca, semplicemente essere l'offset a partire dall'inizio della B1 per i.

In 5.3.1 / 3:

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

Quindi, il trucco è quello di rendere & D :: i essere di tipo B1 :: * in primo luogo. Poi:

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

è semplice. L'interesse viene poi:

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

Qui il RHS è di tipo B1 :: * e ha bisogno di una conversione come abbiamo bisogno di determinare quale di base viene indicato.

Un rapido controllo su ISO IEC 14882 2003 Sezione 10 non ha questo esempio, o qualcosa di simile a questo. C ++ 0x progetto di serie, e VC ++ / GCC / Clang non conformi ad esso.

La mia ipotesi: Questo è un sottoprodotto della nuova tipizzazione auto e non trovato nel vecchio standard di C ++.

FWIW, sto copiando sopra la mia risposta che ho dato alla copia usenet di questa domanda:

Ciao a tutti,

Sono molto confuso circa il livello n3225 10.2 / 13,
[Nota: Anche se il risultato della ricerca del nome è inequivocabile, l'uso di un nome trovato in più sotto-oggetti potrebbero essere ancora ambiguo (4.11, 5.2.5, 5.3.1, 11.2) .- nota estremità] [Esempio:

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
  }
};

Non riesco a capire il motivo per cui questo è inequivocabile int B1 :: * mpB1 = & D :: i; // non ambiguo

&D::i trovi tipo int B1::*, e senza ambiguità riferisce all'elemento dati i di B1. Se dereferenziarlo con un oggetto D o se si assegna a un int  D::*, si otterrà un'ambiguità, se necessario.

Visual C ++, gcc e clang tutti dicono che è l'accesso ambiguo D :: i!

Nessuno di questi compilatori implementare 10.2 ancora.

La formulazione sembra essere correlato alla questione centrale # 39 http://www.open-std.org/jtc1 /sc22/wg21/docs/cwg_defects.html#39 , e la proposta finale è qui: http://www.open-std.org /jtc1/sc22/wg21/docs/papers/2004/n1626.pdf Ora trovo che le nuove formulazioni a base di algoritmo (10,2 / 3-10,2 / 6) sono ancora più confuso perché nessuno di nota in 10.2 / 9, 10,2 / 10, 10.2 / 11, e 10,2 / 13 conforme completamente con 10,2 / 3-10,2 / 6. posso prendere 10.2 / 9-10,2 / 11 come eccezioni, ma sono particolarmente confuso su 10.2 / 13. Non ho idea sull'intenzione di 10.2 / 13.

È necessario dare esempi che mostrano ciò che non si capisce.

Come dovrebbe l'esempio 10.2 / 13 essere guardato-up a seconda del 10.2 / 3-10,2 / 6? Qual è l'intenzione di 10,2 / 13, vale a dire, qual è il situazione di cui 10,2 / 13 è considerata come eccezione di 10.2 / 3-10,2 / 6?

Il nuovo algoritmo basato lookup regole disaccoppia le preoccupazioni di runtime (trovare un oggetto unico) dal momento della compilazione / preoccupazioni di ricerca (trovare una dichiarazione che un nome si riferisce).

Il seguente è ben formato con la nuova formulazione:

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

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

Il using A::x; dichiarazione introduce un nome utente in B che si riferisce a il Z::z dichiarazione. In un contesto dichiarativo, questo è perfettamente bene. Un errore è risorto solo quando si accede B::z come espressione accesso membri (5.2.5).

Non sento male di avere sbagliato questo sul caso puntatore membro. ho fatto così anche in passato, e il corrispondente problema rapporto effettivamente fatto in un C + + progetto 0x. Essi fortuna cambiato indietro quando hanno notato che cambiamento è stato sbagliato.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top