7

以下代码使用 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::nameB解决了这个问题,但是将A::name成员发布给每个人,而它应该只对特定的模板实例可见,即C<B>.

4

2 回答 2

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中没有任何成员namename当您尝试通过类对象访问该成员时,它是范围搜索B

编辑 :

将 using A::name 添加到 B 可以解决问题,但会将 A::name 成员发布给所有人,而它应该只对特定模板实例化可见,即 C

using A::name;如果是这种情况,那么只需在类的私有部分中声明语句,B

struct B : private A {
protected: using A::name; 
public:
friend struct C<B>;
};
于 2012-09-06T07:59:34.993 回答
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++ 上编译(与问题中的错误基本相同)。将不得不咨询谁做对的标准......

于 2012-09-06T08:10:21.487 回答