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