以下代码使用GCC 4.4.6和Comeau 4.3.10进行编译。
#include <iostream>
struct A { int name; };
template<typename T> struct C : T { using T::name; };
struct B : private A { friend struct C<B>; };
int main()
{
C<B> o;
o.name = 0;
}
它在VC ++ 10中出现以下错误:
main.cpp(4): error C2877: 'A::name' is not accessible from 'A' main.cpp(10): error C2247: 'A::name' not accessible because 'B' uses 'private' to inherit from 'A'
什么是允许o.name = 0;
的好的交叉编译器解决方法?
注意:将using A::name
添加到B
会解决问题,但会将A::name
成员发布给所有人,而只应向所有人显示C<B>
成员。特定模板实例化,即{{1}}。
答案 0 :(得分:5)
解决@kerrekSB建议的问题,在课程using A::name;
中添加B
:
struct A { int name; };
template<typename T> struct C : T { using T::name; };
struct B : private A {
using A::name;
friend struct C<B>;
};
您的初始示例无效,因为类A
是B
的私有,而C<B>
类是B
的朋友,但是当您访问成员name
时从C<B>
的对象开始,行using T::name;
会产生问题,因为类B
中没有任何成员name
。它是范围搜索,当您尝试通过类name
的对象访问它时找到该成员B
编辑:
使用A :: name添加到B来解决问题,但是发布了 A :: name成员给每个人,而它应该只对a可见 特定模板实例化,即C
如果是这种情况,那么只需在类using A::name;
的私有部分声明语句B
,即
struct B : private A {
protected: using A::name;
public:
friend struct C<B>;
};
答案 1 :(得分:2)
使用成员using-declarations 时,gcc和VC ++之间的可见性考虑似乎存在根本区别;检查这个没有模板的简化示例:
struct A { int name; };
struct B: private A { friend struct C; };
struct C: B {using B::name; };
int main()
{
C o;
o.name = 0;
}
它将在gcc上编译但不在VC ++上编译(基本上与问题中的错误相同)。将不得不参考关于谁正确行事的标准......