Буде замінити '::' на '. 'створювати двозначності в C ++?


95

У C ++ оператор ::використовується для доступу до класів, функцій та змінних у просторі імен чи класу.

Якщо мовна специфікація, яка використовується .замість ::таких випадків, як і при зверненні до змінних екземплярів / методів об'єкта, це спричинило б можливі двозначності, яких немає ::?

Зважаючи на те, що C ++ не дозволяє імена змінних, які також є назвою типу, я не можу придумати випадок, коли це могло б статися.

Пояснення: я не запитую, чому ::його обрали ., просто, якщо це теж могло працювати?


Коментарі не для розширеного обговорення; ця розмова була переміщена до чату .
Samuel Liew

Відповіді:


124

Завдяки спробам зробити C ++ більшою мірою сумісним з існуючим кодом C (що дозволяє зіткнення імен між іменами об'єктів та тегами Stru), C ++ дозволяє зіткнення імен між іменами класів та іменами об'єктів.

Що означає, що:

struct data {
    static int member;
};

struct data2 {
    int member;
};

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

це законний код.


11
Тож відповідь на запитання в заголовку - Так, так , чи не так?
Енріко Марія Де Анджеліс

2
@EnricoMariaDeAngelis це не так просто. Якщо C ++ розроблявся як абсолютно нова мова, як, наприклад, Java або C #, неоднозначності, можливо, можна уникнути . Але C ++ був розроблений як "C з класами", і тому це не так. "Так, це буде " - це правильна відповідь, але на інше питання.
Комплект.

Почекайте, не лінія присвоювання просто показує , що приміщення .або ::між тими ж двома «словами» має різний ефект ( data.memberвідноситься до memberз dataоб'єкта класу data2, в той час як data::memberвідноситься до memberкласу data)?
Енріко Марія Де Анджеліс

1
Так, але це не те, чим повинні пишатися мовні дизайнери. Це лише артефакт рішень про сумісність.
Комплект.

Гаразд, я розумію, що те, наскільки C ++ є сьогодні і наскільки це було (також), залежить від того, яким був C на той час, коли C ++ розвивався з нього. Але якщо говорити про C ++ таким, яким він є, і залишити осторонь, чому він є таким, як він є, виникли б двозначності, якби все ::було змінено на .. Ви певним чином відповіли так . Я просто не можу порушити вам перший коментар. Можливо, мій рівень змушує цей коментар виглядати димним для мене.
Енріко Марія Де Анджеліс

37

Приклад, коли обидва дійсні, але відносяться до різних об'єктів:

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

Побачити в прямому ефірі на колиру .


І це неможливо було легко вирішити за допомогою різних дизайнерських рішень!
користувач253751

7

Існує різниця між a::bі a.bзвідки ::випливає, що aвикористовується як простір імен, це означає, що це простір імен або ім'я типу. За умови, що C ++ підтримує невіртуальне множинне успадкування і що змінна може мати те саме ім’я, що і тип, це позбавляє шансів на посилання на неправильний об'єкт. Це необхідно для метапрограмування шаблонів.

Інший приклад - &B::fooпорівняно &B.fooз класом B.


2

Нехай розширить приклад @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 on Coliru Viewer

Не маючи можливості диференціювати за допомогою ::, до якого члена ми хочемо отримати доступ, неможливо отримати доступ до членів, оголошених у батьківському класі з однаковими іменами.


A A(ім'я змінної, що також є ім'ям типу), невірно в C ++, тому цей приклад наразі не працює
Jimmy RT

1
@ JimmyR.T. На прикладі Coliru Viewer є приклад трудового життя. Підтвердьте свою заяву, будь ласка, абзацом із стандарту.
SM

якщо б тут додати проклятий алмаз успадкування з тим же самим, з іншого боку, це було б вершиною іменування шизофренії, можливо в C ++
Swift - п’ятниця,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.