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 sí . 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.