C ++ questioni nome membro della classe di ricerca (per quanto riguarda la formulazione di standard di n3225)
-
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.
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.