提问人:Mitsuru Kariya 提问时间:1/10/2014 最后编辑:TemplateRexMitsuru Kariya 更新时间:1/10/2014 访问量:394
友元类声明和 using 指令
friend class declaration and using directive
问:
以下示例的格式是否正确?
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 A
class A
答:
9赞
Dietmar Kühl
1/10/2014
#1
在没有资格的情况下,你会使用N::A
friend
B
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标准应该更清楚地显示这种情况。
评论
N
using namespace N
namespace N
using namespace N
namespace N