微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c – 为什么允许冗余类名限定符?

我遇到了一些这样的代码
struct A {
    A() {}
    A(int) {}
};

struct B : A {
    void init(int i);
};

void B::init(int i) {
    A::A(i); // what is this?
}

int main() {
    B b;
    b.init(2);
}

这个编译并运行使用VC11 beta,没有错误或警告与/ W4.

明显的目的是调用B :: init来重新初始化B的A基本子对象.我相信它实际上解析为一个名为i的类型为A的变量声明.使用clang编译生成诊断:

ConsoleApplication1.cpp:11:14: warning: declaration shadows a local variable
        A::A(i);
             ^
ConsoleApplication1.cpp:10:22: note: prevIoUs declaration is here
    void B::init(int i) {
                     ^
ConsoleApplication1.cpp:11:14: error: redeFinition of 'i' with a different type
        A::A(i);
             ^
ConsoleApplication1.cpp:10:22: note: prevIoUs deFinition is here
    void B::init(int i) {
                     ^

看起来好奇的是,可以使用冗余类资格来引用该类型.

此外,A :: A(i)似乎被VS11和clang / gcc不同的解析.如果我做A :: A(b)clang和gcc使用认构造函数创建类型A的变量b.这个说法的VS11错误一个未知的标识符.使用构造函数A :: A(int)创建一个临时的A作为参数,VS11似乎解析A :: A(i).当冗余限定符被消除时,将解析源作为变量声明,如clang和gcc do,并产生一个类似的错误,关于阴影变量i.

解析这个差异解释了为什么VS11会扼制多于一个额外的限定词; A :: A :: A :: A(i),为什么,由于clang和gcc可以接受一个额外的限定词,任何多于一个的数字与一个额外的结果相同.

这是另一个上下文中冗余限定词的另一个例子.所有编译器似乎都将其解析为临时构造:

class Foo {};

void bar(Foo const &) {}

int main() {
    bar(Foo::Foo());
}

>为什么允许冗余限定词?
>有一些上下文可以引用构造函数,例如继承构造函数的语法(类D:B {using B :: B;};)),但是VS似乎允许它在任何地方. VS错了,cl ang cl and and cc cl cl cl cl?????????????
>我知道VS在标准合规性方面仍然有一点落后,但是我确实发现,现代的积极开发的编译器可能会如此分歧,在这种情况下,将一个冗余限定词作为构造函数名称(甚至虽然构造函数没有名称)而不是简单地将冗余限定词解析为类型,导致VS构造一个临时的,其他人声明一个变量. B b(A :: A(i));被clang和gcc解析为最令人烦恼的解析,但是VS看到它用一个初始化器声明一个类型B的变量b.这个严重的还有很多差异吗?
>显然,在便携式代码中应避免冗余限定符.有没有一个很好的方法来防止这种构造被使用?

解决方法

虽然这种现象可能归因于类名注入,正如在ephemient的答案中所指出的,对于这个具体的例子,C语言已经被非法使用了.

http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#147

组合A :: A需要引用类构造函数,而不是类注入的名称. A :: A(i)应该被兼容的编译器解释为涉及构造函数名称的非法(因此是无意义的)表达式.例如,Comeau编译器将拒绝编译您的代码.

显然,VC11继续将A :: A作为注入类名的参考.有趣的是,我在VS2005中没有观察到这个问题.

在A :: A被解释为指向注入名称的那一天,可以声明一个A对象

A::A::A::A::A::A a;

等等,任意数量的As.但不再是令人惊讶的是,由Ideaone使用的GCC版本(4.3.4?)仍然受到这个问题的困扰

http://ideone.com/OkR0F

您可以尝试使用您的VC11版本,看看它是否允许.

原文地址:https://www.jb51.cc/c/113915.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐