13

以下示例格式正确吗?

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 说,

如果friend声明中的名称既不是限定词也不是模板标识,并且声明是函数或详细类型说明符,则确定实体是否先前已声明的查找不应考虑最内层封闭命名空间之外的任何范围。

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

4

2 回答 2

9

使您N::A没有资格friend使用B

friend A;

而不是

friend class A;

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

于 2014-01-09T20:08:33.577 回答
1

虽然使用命名空间 N 将名称 N::A 拉入全局命名空间,但它并没有在全局命名空间中声明 A。因此,全局命名空间中的附加 A 是 B 的朋友。clang 是错误的。

于 2014-01-09T20:34:53.603 回答