Буде замінити '::' на '. 'створювати двозначності в 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.