友元类声明和 using 指令

friend class declaration and using directive

提问人:Mitsuru Kariya 提问时间:1/10/2014 最后编辑:TemplateRexMitsuru Kariya 更新时间:1/10/2014 访问量:394

问:

以下示例的格式是否正确?

namespace N {
    class A;
}
using namespace N;

class B {
    int i;
    friend class A;
};

namespace N {
    class A {
        B m;
        int get() { return m.i; }
    };
}

此示例使用 Clang 3.5 成功编译,但在 g++ 4.8.1 中失败,并出现以下问题:

main.cpp: In member function ‘int N::A::get()’:
main.cpp:7:9: error: ‘int B::i’ is private
     int i;
         ^
main.cpp:14:30: error: within this context
         int get() { return m.i; }
                              ^

C++11 标准 §7.3.1.2 p3 说,

如果声明中的名称既不是限定的,也不是 template-id,并且声明是函数或精心设计的类型说明符,则用于确定实体是否先前已声明的查找不应考虑最内层封闭命名空间之外的任何范围。friend

例如,不是最里面封闭命名空间(即全局命名空间)的成员,而是通过使用指令引入到全局命名空间中。class Aclass A

C++ 命名空间 friend using-directives name-lookup

评论

0赞 ichramm 1/10/2014
由于 ,您正在 N 中创建一个嵌套命名空间,请尝试删除最后一个Nusing namespace Nnamespace N
2赞 Praetorian 1/10/2014
@ichramm并不意味着后面的所有内容都隐含地属于using namespace Nnamespace N
0赞 ichramm 1/10/2014
@LightnessRacesinOrbit @Praetorian直到我测试了上面的代码注释掉最后一个“命名空间 N”,我不确定,这很奇怪,我知道。
0赞 Lightness Races in Orbit 1/10/2014
@ichramm:这不仅很奇怪,而且是不真实的。你正在观察别的东西。
1赞 Alan Stokes 1/10/2014
@ichramm 你的实验是令人钦佩的,你的结论却不那么令人钦佩。

答:

9赞 Dietmar Kühl 1/10/2014 #1

在没有资格的情况下,你会使用N::AfriendB

friend A;

而不是

friend class A;

当使用详细的类型说明符时,即 ,并且它采用这种特定形式,它引入了一个类名(参见 3.4.4 [basic.lookup.elab] 第 2 段)。class A

评论

0赞 dyp 1/10/2014
据我所知,[basic.lookup.elab]/2 中提到的表格不包含。所以这里提到的表格是朋友声明的一部分。它仍然适用吗?friend
0赞 Dietmar Kühl 1/10/2014
@dyp:是的,我知道。但是,是否匹配表达式“.* class-key attribute-specifier-seq?identifier;”。我认为其目的是将其与 or 等用法区分开来,我认为它确实适用。friend class A;class foo f();int stat(struct stat*)
1赞 user2249683 1/10/2014 #2

使用命名空间 N 将名称 N::A 拉入全局命名空间时,它不会在全局命名空间中声明 A。因此,全局命名空间中的额外 A 是 B 的朋友。

评论

0赞 Mitsuru Kariya 1/10/2014
@Diether C++11 标准 7.3.4 p2 说“在非限定名称查找 (3.4.1) 期间,名称看起来好像是声明的......”,而 3.4.1 p2 说“就 3.4.1 中描述的非限定名称查找规则而言,using 指令指定的命名空间中的声明被视为该封闭命名空间的成员”。
1赞 Mitsuru Kariya 1/10/2014
@Diether:谢谢!你说得很对!我找到了问题 N1229。但是,我认为C++11标准应该更清楚地显示这种情况。