会将'::'替换为'。在C ++中造成歧义?


95

在C ++中,运算符::用于访问名称空间或类中的类,函数和变量。

如果使用语言规范.代替::访问对象的实例变量/方法时那样,而不是在那种情况下,那么是否会引起可能不存在的歧义::

鉴于C ++不允许变量名也是类型名,因此我认为这种情况不会发生。

澄清:我不是问为什么::选择了.,即使它也可以工作?


评论不作进一步讨论;此对话已转移至聊天
塞缪尔·柳

Answers:


124

由于试图使C ++与现有的C代码最兼容(允许对象名称和struct标记之间发生名称冲突),因此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.membermemberdata是class 的object data2,而data::membermember的是class的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';
}

现场直播coliru


而且使用不同的设计决策无法轻松解决这一难题!
user253751

7

有区别a::b,并a.b在那里::暗示a用作名称空间,这意味着它是名称空间或类型名。如果C ++支持非虚拟的复数继承,并且变量可以与类型具有相同的名称,则这将消除引用错误对象的机会。这是模板元编程所必需的。

另一个示例是B类上下文中的&B::foovs。&B.foo


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上直播

无法通过::来区分我们想要访问的成员,因此不可能访问在父类中声明的具有相同名称的成员。


A A(变量名也为类型名)在C ++中无效,因此此示例暂时不起作用
Jimmy RT

1
@ JimmyR.T。Coliru Viewer上有工作寿命示例。请使用标准中的一段确认您的声明。
SM

如果有人在这里添加被诅咒的继承钻石,并在另一侧添加相同的东西,那将是命名精神分裂症的巅峰之作-C ++
Swift-Friday Pie
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.