Заменил бы '::' на '. создать неясности в C ++?

95

В C ++ оператор ::используется для доступа к классам, функциям и переменным в пространстве имен или классе.

Если бы спецификация языка использовалась .вместо того, чтобы ::в тех случаях, например, при доступе к переменным / методам экземпляра объекта, вызывать ли это возможные неоднозначности, которых нет ::?

Учитывая, что C ++ не допускает имен переменных, которые также являются именами типов, я не могу вспомнить случай, когда это могло произойти.

Пояснение: я не спрашиваю, почему ::был выбран ., просто если бы это тоже сработало?

Джимми Р.Т.
источник
Комментарии не для расширенного обсуждения; этот разговор был перенесен в чат .
Самуэль Лью

Ответы:

124

Из-за попыток сделать C ++ главным образом совместимым с существующим кодом C (который допускает конфликты имен между именами объектов и тегами структуры), 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';
}

Смотрите вживую на колиру .

Deduplicator
источник
И это не может быть легко решено с помощью различных дизайнерских решений!
user253751
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.
}

Жить на Coliru Viewer

Не имея возможности различить с помощью ::, к какому члену мы хотим получить доступ, невозможно получить доступ к членам, объявленным в родительском классе с одинаковыми именами.

SM
источник
A A(имя переменной, также являющееся именем типа) недопустимо в C ++, поэтому этот пример пока не работает
Jimmy RT
1
@ JimmyR.T. На Coliru Viewer есть пример трудовой жизни. Подтвердите свое утверждение, пожалуйста, абзацем из стандарта.
SM
если бы сюда добавили проклятый алмаз наследования с той же вещью на другой стороне, это была бы вершина именования шизофрении, возможного в C ++
Swift - Friday Pie