Sostituire '::' con '. "creare ambiguità in C ++?


95

In C ++, l'operatore :: viene utilizzato per accedere a classi, funzioni e variabili in uno spazio dei nomi o in una classe.

Se le specifiche del linguaggio utilizzate .invece che ::in quei casi anche come quando si accede a variabili / metodi di istanza di un oggetto, ciò causerebbe possibili ambiguità che non sono presenti ::?

Dato che C ++ non consente nomi di variabili che sono anche un nome di tipo, non riesco a pensare a un caso in cui ciò possa accadere.

Chiarimento: non sto chiedendo perché è ::stato scelto ., solo se avrebbe potuto funzionare anche tu?


I commenti non sono per una discussione estesa; questa conversazione è stata spostata in chat .
Samuel Liew

Risposte:


124

A causa dei tentativi di rendere il C ++ per lo più compatibile con il codice C esistente (che consente collisioni di nomi tra nomi di oggetti e tag struct), C ++ consente collisioni di nomi tra nomi di classi e nomi di oggetti.

Che significa che:

struct data {
    static int member;
};

struct data2 {
    int member;
};

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

è un codice legittimo.


11
Quindi la risposta alla domanda nel titolo è Sì, non è vero?
Enrico Maria De Angelis,

2
@EnricoMariaDeAngelis non è così semplice. Se il C ++ fosse sviluppato come un linguaggio completamente nuovo, come Java o C #, l'ambiguità potrebbe probabilmente essere evitabile . Ma C ++ è stato sviluppato come "C con classi", ed è per questo che non lo è. "Sì, lo sarà " è una risposta corretta, ma a una domanda diversa.
Kit.

Attesa, non è la linea assegnazione solo mostrando che mettere .o ::tra gli stessi due "parole" ha effetto diverso ( data.membersi riferisce alla memberdella dataoggetto della classe data2, che data::membersi riferisce alla memberdella classe data)?
Enrico Maria De Angelis,

1
Sì, ma non è qualcosa di cui i designer linguistici dovrebbero essere orgogliosi. È solo un artefatto delle decisioni di compatibilità.
Kit.

Ok, capisco che come C ++ è oggi ed è stato finora (anche) dipende da quale C era al momento in cui C ++ si è sviluppato da esso. Ma parlando del C ++ così com'è, e tralasciando il motivo per cui è così, ci sarebbe un'ambiguità se tutto ::fosse cambiato in .. In un certo senso hai già risposto . Semplicemente non posso violare il tuo primo commento. Forse il mio livello mi fa sembrare fumoso quel commento.
Enrico Maria De Angelis,

37

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

Guarda dal vivo su coliru .


E questo non può essere facilmente risolto con diverse decisioni di progettazione!
user253751

7

C'è differenza tra a::be a.bdove ciò ::implicaa usato come spazio dei nomi, il che significa che è spazio dei nomi o nome del tipo. A condizione che C ++ supporti l'ereditarietà plurale non virtuale e che una variabile possa avere lo stesso nome di un tipo, ciò riduce le possibilità di fare riferimento a un oggetto errato. È necessario per la metaprogrammazione dei modelli.

Un altro esempio sarebbe &B::foovs &B.foonel contesto della classe B.


2

Consentiamo di estendere l'esempio di @Deduplicator:

#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 su Coliru Viewer

Non avendo la possibilità di differenziare con l'aiuto di ::, a quale membro vogliamo accedere, è impossibile accedere ai membri dichiarati in una classe genitore con nomi identici.


A A(il nome della variabile che è anche un nome di tipo) non è valido in C ++, quindi questo esempio non funziona per ora
Jimmy RT

1
@ JimmyR.T. C'è l'esempio della vita lavorativa su Coliru Viewer. Conferma la tua dichiarazione per favore con un paragrafo dalla norma.
SM

se uno aggiungesse qui il diamante ereditario maledetto con la stessa cosa dall'altra parte, sarebbe un apice della denominazione della schizofrenia possibile in C ++
Swift - Friday Pie
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.