friend类声明和using指令

时间:2014-01-09 19:36:03

标签: c++ namespaces friend using-directives name-lookup

以下示例是否格式正确?

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.2p3说,

  

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

在示例中,class A不是最内层封闭命名空间(即全局命名空间)的成员,但是class A是通过将指令引入全局命名空间引入的。

2 个答案:

答案 0 :(得分:8)

要使N::A无法获得friend B你要使用

friend A;

而不是

friend class A;

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

答案 1 :(得分:1)

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