In C++, l'operatore ::
è usato per accedere a classi, funzioni e variabili in uno spazio dei nomi o in una classe.
Se la specifica del linguaggio usasse .
invece di ::
anche in questi casi, come quando si accede a variabili/metodi di istanza di un oggetto, ciò causerebbe possibili ambiguità che non sono presenti con ::
?
Dato che il C++ non permette nomi di variabili che siano anche un nome di tipo, non riesco a pensare ad un caso in cui questo potrebbe accadere.
Chiarimento: Non sto chiedendo perché ::
è stato scelto rispetto a .
, solo se avrebbe potuto funzionare anche questo?
A causa dei tentativi di rendere il C++ maggiormente compatibile con il codice C esistente (che permette collisioni di nomi tra nomi di oggetti e tag struct), il C++ permette collisioni di nomi tra nomi di classi e nomi di oggetti.
Il che significa che:
struct data {
static int member;
};
struct data2 {
int member;
};
void f(data2& data) {
data.member = data::member;
}
è un codice legittimo.
Un esempio in cui entrambi sono validi, ma si riferiscono a oggetti diversi:
#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';
}
Vedi live su coliru.
C'è differenza tra a::b
e a.b
dove ::
implica che a
è usato come namespace, il che significa che è namespace o typename. A condizione che il C++ supporti l'eredità plurale non virtuale e che una variabile possa avere lo stesso tipo, questo elimina le possibilità di referenziare un oggetto sbagliato. È necessario per la metaprogrammazione dei template.
Un altro esempio potrebbe essere &B::foo
vs &B.foo
nel contesto della classe B.
Estendere l'esempio di @Deduplicatore:
#include <iostream>
struttura A {
int i;
};
struttura B : pubblico A {
int i;
A;
};
int main() {
B x {1, 2};
std::cout << x.i << '\n';
std::cout << x.B::i << '\n'; // Lo stesso della riga sopra.
std::cout << x.A.i << '\n';
std::cout << x.A::i << '\n'; // Non è la stessa della riga sopra.
}
Non avendo la possibilità di differenziare con l'aiuto di ::, a quale membro vogliamo accedere, è impossibile accedere ai membri dichiarati in una classe di genitori con nomi identici.