asuntos nombre de miembro de la clase de búsqueda C ++ (en cuanto a la redacción de la norma N3225)

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

  •  13-10-2019
  •  | 
  •  

Pregunta

Estoy muy confundido sobre el estándar 10.2 / 13,

[Nota: Incluso si el resultado de la búsqueda de nombres no es ambigua, el uso de un nombre encontrado en múltiples sub-objetos aún puede ser ambiguo (4.11, 5.2.5, 5.3.1, 11.2) .- nota final] [Ejemplo:

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

No puedo ver por qué esto no es ambigua int B1 :: * mpB1 = + D :: i; // inequívoca

Visual C ++, GCC y CLANG todos dicen que es ambigua acceso a D :: i!

La redacción parece estar relacionado con el tema central # 39 http://www.open-std.org/jtc1 /sc22/wg21/docs/cwg_defects.html#39 , y la propuesta final está aquí: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1626.pdf

Ahora se encontró que las nuevas formulaciones basadas en algoritmos (10.2 / 3-10.2 / 6) están confundiendo aún más debido a que ninguno de la nota de 10,2 / 9, 10.2 / 10, 10.2 / 11, y 10.2 / 13 Cumple totalmente a 10,2 / 3-10.2 / 6. Puedo tomar 10.2 / 9-10,2 / 11 como excepciones, pero estoy confundido especialmente aproximadamente 10,2 / 13. No tengo ni idea de la intención de 10,2 / 13.

¿Cómo debe el ejemplo de 10,2 / 13 se veía en marcha de acuerdo con el 10.2 / 3-10.2 / 6? ¿Cuál es la intención de 10,2 / 13, es decir, ¿cuál es la situación que 10,2 / 13 se considera como una excepción de 10.2 / 3-10.2 / 6?

Por favor, dame algunos consejos. Muchas gracias.


Después de pensar un poco, creo que la intención de 10,2 / 13 es más claro para mí.

int B1 :: * mpB1 = + D :: i; // inequívoca

Esto debe ser inequívoca y los compiladores actuales están mal en esto. Esto no es ambigua porque puntero a miembros de la clase de inicialización no involucra en el acceso al objeto todavía.

int D :: * MPD = + D :: i; // conversión Ambiguous

En realidad, esto significa que convertir de int B1 :: * mpB1 a int D :: * MPD, la conversión es ambigua debido a las clases base ambiguas.

¿Fue útil?

Solución

Este:

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

Es ambigua porque el resultado se asigna a un pointer to member de la clase B.
Por lo tanto, no importa que i es elegido como el desplazamiento es relativo a un miembro de B (no de la clase padre D).

Por lo tanto, no es ambigua a usted ya mí, pero no creo que el compilador puede manejarlo.

Otros consejos

Para el B1 :: * caso, la interpretación no es ambigua, siendo simplemente el desplazamiento desde el inicio de B1 a i.

En 5.3.1 / 3:

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

Así que el truco es hacer + D :: i ser de tipo B1 :: * en el primer lugar. A continuación:

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

es simple. El interés y luego entra en juego:

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

Aquí el lado derecho es de tipo B1 :: * y necesita una conversión, ya que necesitamos para determinar qué base se hace referencia.

Una revisión rápida en la norma ISO IEC 14882 2003 Sección 10 no tiene este ejemplo, ni nada similar a esto. C ++ 0x es proyecto estándar, y VC ++ / GCC / CLANG no son compatibles con ella.

Mi conjetura: Esto es cierto subproducto de la nueva tipificación auto y no se encuentra en mayor estándar de C ++.

Fwiw, estoy copiando sobre mi respuesta que he dado a la copia de Usenet de esta pregunta:

Hola a todos,

Estoy muy confundido acerca de la norma N3225 10,2 / 13,
[Nota: Incluso si el resultado de la búsqueda de nombres no es ambigua, el uso de una nombre que se encuentra en varios subobjetos aún podría ser ambiguo (4.11, 5.2.5, 5.3.1, 11.2) .- nota final] [Ejemplo:

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

No puedo ver por qué esto no es ambigua int B1 :: * mpB1 = + D :: i; // sin ambigüedades

&D::i tiene tipo int B1::*, y sin ambigüedad se refiere a miembro de datos i de B1. Si deferenciarlo con un objeto D o si lo ha asignado a un int  D::*, obtendrá una ambigüedad, según sea necesario.

Visual C ++, GCC y CLANG todos dicen que es ambigua acceso a D :: i!

Ninguno de los compiladores implementar 10,2 todavía.

La redacción parece estar relacionado con el tema central # 39 http://www.open-std.org/jtc1 /sc22/wg21/docs/cwg_defects.html#39 , y la propuesta final está aquí: http://www.open-std.org /jtc1/sc22/wg21/docs/papers/2004/n1626.pdf Ahora me parece que las nuevas formulaciones basadas en algoritmos (10.2 / 3-10.2 / 6) son Aún más confuso porque ninguno de la nota de 10,2 / 9, 10.2 / 10, 10,2 / 11, y 10,2 / 13 cumple plenamente con 10,2 / 3-10.2 / 6. yo puedo llevar 10.2 / 9-10,2 / 11 como excepciones, pero estoy confundido acerca de todo 10,2 / 13. No tengo ni idea de la intención de 10,2 / 13.

Se necesita dar ejemplos que muestran lo que no entiende.

¿Cómo debería el ejemplo de 10,2 / 13 se parecía-up de acuerdo con la 10.2 / 3-10.2 / 6? ¿Cuál es la intención de 10,2 / 13, es decir, ¿cuál es la situación de la que 10,2 / 13 se considera como una excepción de 10.2 / 3-10.2 / 6?

El nuevo algoritmo de búsqueda basado en reglas desacopla preocupaciones de tiempo de ejecución (la búsqueda de una objeto único) de tiempo de compilación / preocupaciones de búsqueda (búsqueda de una declaración de que un nombre se refiere a).

La siguiente es bien formado con la nueva formulación:

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

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

El using A::x; declaración introduce un nombre de miembro en B que se refiere a Z::z la declaración. En un contexto declarativo, esto está perfectamente bien. Un de error se ha levantado sólo cuando se accede a B::z como una expresión del acceso de miembros (5.2.5).

No se sienta mal por tener esta equivocada sobre el caso puntero del miembro. lo hacía demasiado en el pasado, y la correspondiente informe cuestión de hecho lo hizo en un C + + 0x proyecto. Que afortunadamente cambiaron de nuevo cuando se dieron cuenta de que cambio fue incorrecto.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top