Zamieniłbym „::” na „. „tworzyć dwuznaczności w C ++?


95

W C ++ operator ::służy do uzyskiwania dostępu do klas, funkcji i zmiennych w przestrzeni nazw lub klasie.

Jeśli specyfikacja języka zastosowana .zamiast ::w tych przypadkach jest zbyt podobna do uzyskiwania dostępu do zmiennych instancji / metod obiektu, to czy spowodowałoby to możliwe niejasności, których nie ma ::?

Biorąc pod uwagę, że C ++ nie dopuszcza nazw zmiennych, które są również nazwami typów, nie mogę wymyślić przypadku, w którym mogłoby się to zdarzyć.

Wyjaśnienie: Nie pytam, dlaczego ::wybrano ., tylko czy to mogło zadziałać?


Komentarze nie są przeznaczone do rozszerzonej dyskusji; ta rozmowa została przeniesiona do czatu .
Samuel Liew

Odpowiedzi:


124

Z powodu prób uczynienia C ++ w większości kompatybilnym z istniejącym kodem C (który pozwala na kolizje nazw między nazwami obiektów i znacznikami struktury), C ++ pozwala na kolizje nazw między nazwami klas a nazwami obiektów.

Co oznacza że:

struct data {
    static int member;
};

struct data2 {
    int member;
};

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

jest legalnym kodem.


11
Tak więc odpowiedź na pytanie w tytule brzmi: tak, prawda , prawda?
Enrico Maria De Angelis

2
@EnricoMariaDeAngelis to nie jest takie proste. Gdyby C ++ został opracowany jako zupełnie nowy język, taki jak Java lub C #, dwuznaczności można by prawdopodobnie uniknąć . Ale C ++ został opracowany jako „C z klasami” i dlatego tak nie jest. „Tak, będzie ” to poprawna odpowiedź, ale na inne pytanie.
Zestaw

Wait nie jest linia zadanie to pokazano, że wprowadzenie .lub ::pomiędzy dwoma „słowa” posiada inny efekt ( data.memberodnosi się do membertego dataobiektu klasy data2, przy czym data::memberodnosi się do memberklasy data)?
Enrico Maria De Angelis

1
Tak, ale nie jest to coś, z czego projektanci powinni być dumni. To tylko artefakt decyzji dotyczących zgodności.
Zestaw

Ok, rozumiem, że to, jak C ++ jest dzisiaj i do tej pory (także), zależy od tego, jakie C było w czasie, gdy C ++ z niego rozwinął. Ale mówiąc o C ++ w obecnej postaci i pomijając dlaczego tak jest, nie byłoby dwuznaczności, gdyby wszystkie ::zostały zmienione na .. W pewien sposób odpowiedziałeś już tak . Po prostu nie mogę wniknąć w twój pierwszy komentarz. Może mój poziom sprawia, że ​​ten komentarz wydaje mi się zadymiony.
Enrico Maria De Angelis

37

Przykład, w którym oba są poprawne, ale odnoszą się do różnych obiektów:

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

Zobacz na żywo na coliru .


Tego nie da się łatwo rozwiązać przy pomocy różnych decyzji projektowych!
user253751

7

Istnieje różnica między a::bi a.bgdzie ::implikuje to, że jest aużywana jako przestrzeń nazw, co oznacza, że ​​jest to przestrzeń nazw lub nazwa typu. Pod warunkiem, że C ++ obsługuje nie-wirtualne dziedziczenie liczby mnogiej i że zmienna może mieć taką samą nazwę jak typ, eliminuje to ryzyko odniesienia do niewłaściwego obiektu. Jest to konieczne do metaprogramowania szablonu.

Innym przykładem może być &B::foovs &B.foow kontekście klasy B.


2

Pozwól rozszerzyć przykład @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.
}

Na żywo w Coliru Viewer

Nie mając możliwości rozróżnienia za pomocą ::, do którego członka chcemy uzyskać dostęp, nie można uzyskać dostępu do członków zadeklarowanych w klasie nadrzędnej o identycznych nazwach.


A A(nazwa zmiennej, która jest również nazwą typu) nie jest jednak poprawna w C ++, więc ten przykład na razie nie działa
Jimmy RT

1
@ JimmyR.T. Istnieje przykład z życia zawodowego w Coliru Viewer. Potwierdź swoje oświadczenie, paragrafem ze standardu.
SM

jeśli dodamy tutaj przeklęty diament dziedziczenia z tą samą rzeczą po drugiej stronie, byłoby to możliwe nazywanie schizofrenii w C ++
Swift - Friday Pie
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.