【问题标题】:Is it legal to friend a function via a using declaration?通过 using 声明与函数为友是否合法?
【发布时间】:2013-03-28 21:39:12
【问题描述】:

以下(LiveWorkspace here) 被 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 (!) 崩溃。我已经提交了一个错误报告和patch,用于崩溃错误,但我不能 100% 确定这段代码是否真的有错误,因为我在 §7.3.3 [ namespace.udecl]§11.3 [class.friend] 明确解决了这种情况,但也许在我错过的各种名称说明符术语之一的定义中有些东西。

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

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

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

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

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

编辑This is patched now in clang/trunk!

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

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

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

【问题讨论】:

    标签: c++ language-lawyer


    【解决方案1】:

    8.3p1:

    当 declarator-id 合格时, 声明应引用限定符所指向的类或命名空间的先前声明的成员 引用(或者,在命名空间的情况下,该命名空间 (7.3.1) 的内联命名空间集合的元素) 或其专业化; 成员不应仅仅由 using 声明引入 在由 declarator-id 的nested-name-specifier 指定的类或命名空间的范围内。

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

    【讨论】:

    • 那为什么class版本没问题?
    • 好的,+1,对我来说很有意义。好东西,否则这将需要更多的努力来修复:D
    • 我不知道其中的原因。这正是规则出现在规范中的地方。如果这对您有帮助,我很高兴。
    • naw,我真的不在乎,只要确保我在做正确的事情 :) 如果您想详细说明 declarator-id 和详细说明的类型说明符之间的区别可能对遇到此问题的其他人有所帮助,但如果没有,我将自己阅读。
    • 嘿,你能看看我最新的编辑,看看你是否能弄清楚 GCC 和 ICC 是否有任何理由拒绝它?它不使用限定名称。
    猜你喜欢
    • 1970-01-01
    • 2013-11-19
    • 1970-01-01
    • 2011-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-04
    • 1970-01-01
    相关资源
    最近更新 更多