c – 匿名命名空间中模板化类的朋友
当声明A类作为B类的朋友时,A在匿名命名空间内定义而B在外部定义,而某些编译器产生错误“受保护成员不可访问”,而其他编译器不产生任何错误或警告.如果A或B或两者都是模板,情况会发生变化:
namespace { template <class T> struct A { template <class BB> void foo(BB const& b) { b.bar(); } }; } // end anonymous namespace template <class T> class B { template <class> friend struct A; protected: void bar() const {} }; int main() { A<int> a; a.foo(B<int>{}); } > A和B都是模板.然后Intel icc 18:错误#308:函数“B< T> :: bar [with T = int]”无法访问,gcc 7.2:没有错误,clang 5.0:没有错误 有关案例6,请参阅编译器资源管理器中的示例:https://godbolt.org/g/6Zdr3c和https://godbolt.org/g/BRqf78. 那么,正确的行为是什么?哪个编译器正确? 解决方法
据我所知,从标准来看,给定代码在案例1-4中是正确的,并且应该在没有诊断的情况下进行编译:
未命名的命名空间(7.3.1.1:1)的定义指出,未命名的命名空间定义等同于定义具有转换单元唯一名称的命名命名空间,然后使用using指令导入该命名空间. 这将使A的声明在全球范围内可获得,并根据第11.3:9段
因此参数化的类A是B的朋友,并且应该能够访问B :: bar 在案例5中存在差异.据我所知,friend声明在封闭范围内声明了一个新的参数化类A,它与未命名的命名空间中的类A不同. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |