Reemplazaría '::' con '. 'crear ambigüedades en C ++?


95

En C ++, el operador ::se utiliza para acceder a clases, funciones y variables en un espacio de nombres o clase.

Si la especificación de lenguaje utilizada en .lugar de ::en esos casos también es como cuando se accede a las variables / métodos de instancia de un objeto, ¿eso causaría posibles ambigüedades que no están presentes ::?

Dado que C ++ no permite nombres de variables que también son un nombre de tipo, no puedo pensar en un caso en el que eso pueda suceder.

Aclaración: no estoy preguntando por qué ::se eligió ., sino si también podría haber funcionado.


Los comentarios no son para discusión extendida; Esta conversación se ha movido al chat .
Samuel Liew

Respuestas:


124

Debido a los intentos de hacer que C ++ sea principalmente compatible con el código C existente (que permite colisiones de nombres entre nombres de objetos y etiquetas de estructura), C ++ permite colisiones de nombres entre nombres de clase y nombres de objetos.

Lo que significa que:

struct data {
    static int member;
};

struct data2 {
    int member;
};

void f(data2& data) {
    data.member = data::member;
}

Es un código legítimo.


11
Entonces la respuesta a la pregunta en el título es Sí, lo sería , ¿no?
Enrico Maria De Angelis

2
@EnricoMariaDeAngelis no es tan simple. Si C ++ se desarrollara como un lenguaje completamente nuevo, como Java o C #, la ambigüedad probablemente podría evitarse . Pero C ++ se desarrolló como "C con clases", y por eso no lo es. "Sí, lo hará " es una respuesta correcta, pero a una pregunta diferente.
Kit

Esperar, no es la línea de asignación simplemente mostrando que poner .o ::entre los mismos dos "palabras" tiene efecto diferente ( data.memberse refiere a la memberdel dataobjeto de la clase data2, mientras que data::memberse refiere a la memberde la clase data)?
Enrico Maria De Angelis

1
Sí, pero no es algo de lo que los diseñadores de idiomas deberían estar orgullosos. Es solo un artefacto de decisiones de compatibilidad.
Kit

Ok, entiendo que cómo es C ++ hoy y hasta ahora (también) depende de qué era C en el momento en que C ++ se desarrolló a partir de él. Pero hablando de C ++ tal como es, y dejando a un lado por qué es como es, habría una ambigüedad si todos ::se cambiaran a .. En cierto modo ya respondiste que . Simplemente no puedo entrar en tu primer comentario. Tal vez mi nivel hace que ese comentario me parezca lleno de humo.
Enrico Maria De Angelis

37

Un ejemplo donde ambos son válidos, pero se refieren a diferentes objetos:

#include <iostream>

struct A {
    int i;
};

struct B {
    int i;
    A B;
};

int main() {
    B x {0, 1};
    std::cout << x.B.i << '\n';
    std::cout << x.B::i << '\n';
}

Ver en vivo en coliru .


¡Y este no podría resolverse fácilmente con diferentes decisiones de diseño!
user253751

7

Hay una diferencia entre a::by a.bdonde ::implica que se ausa como espacio de nombres, lo que significa que es un espacio de nombres o nombre de tipo. Siempre que C ++ admita la herencia plural no virtual y que una variable pueda tener el mismo nombre que un tipo, esto elimina las posibilidades de hacer referencia a un objeto incorrecto. Es necesario para la metaprogramación de plantillas.

Otro ejemplo sería &B::foovs &B.fooen el contexto de la clase B.


2

Dejemos extender @Deduplicator ejemplo:

#include <iostream>

struct A {
    int i;
};

struct B : public A {
    int i;
    A A;
};

int main() {
    B x {1, 2};
    std::cout << x.i << '\n';
    std::cout << x.B::i << '\n';  // The same as the line above.
    std::cout << x.A.i << '\n';
    std::cout << x.A::i << '\n';  // Not the same as the line above.
}

Live on Coliru Viewer

Al no tener la posibilidad de diferenciar con ayuda de ::, a qué miembro queremos acceder, es imposible acceder a los miembros declarados en una clase principal con nombres idénticos.


A A(nombre de variable que también es un nombre de tipo) no es válido en C ++, por lo que este ejemplo no funciona por ahora
Jimmy RT

1
@ JimmyR.T. Existe el ejemplo de la vida laboral en Coliru Viewer. Confirme su declaración por favor con un párrafo de la norma.
SM

si uno añadiera el diamante de herencia maldito aquí con la misma cosa en el otro lado, sería un pináculo de la esquizofrenia de denominación posible en C ++
Swift - Friday Pie
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.