5

以下(此处为 LiveWorkspace)被 GCC 4.7.2、GCC 4.8.0 和 ICC 13.0.1 拒绝。

namespace A {
    namespace B {
        void C();
    }
    using B::C;
}

class D {
    friend void A::C();
};

此外,它会使 Clang 3.2 (!) 崩溃。我已经为崩溃错误提交了错误报告和补丁,但我不能 100% 确定这段代码是否真的有错误,因为我在§7.3.3 [namespace.udecl]§11.3 [class.friend]明确解决了这种情况,但也许在我错过的各种名称说明符术语之一的定义中有些东西。

此外,似乎所有四个编译器都接受以下内容(此处为 LiveWorkspace)

namespace A {
    namespace B {
        class C;
    }
    using B::C;
}

class D {
    friend class A::C;
};

这两个案例似乎没有什么根本不同,所以我很好奇 GCC 和 ICC 拒绝第一个例子但不是这个例子的理由是什么,如果有的话。任何更熟悉该标准的人都可以找到解决此问题的任何内容吗?

这绝对是一个小问题,但由于我正在修补它,我想确保我做的是正确的事情......

编辑现在在 clang/trunk 中进行了修补!

新编辑:Johannes 在下面的回答解释了为什么我的原始示例被拒绝,但似乎没有解释为什么 GCC 和 ICC 也拒绝以下内容(此处为 LiveWorkspace)

namespace A {
    namespace B {
        void C();
    }
    using B::C;

    class D {
        friend void C();
    };
}
4

1 回答 1

4

8.3p1:

当 declarator-id 被限定时,声明应引用限定符所指的类或命名空间的先前声明的成员(或者,在命名空间的情况下,该命名空间的内联命名空间集合的元素(7.3 .1)) 或其专业化;该成员不应仅由声明符 id 的嵌套名称说明符指定的类或命名空间范围内的 using 声明引入。

A class foo;orclass foo::bar;不包含 declarator-id,因此不受此规则的影响。相反,它foo::bar是详细类型说明符(7.1.6.3)的一部分。

于 2013-03-28T21:45:57.957 回答