错误的私人基类无法访问?

使用g ++ 4.2.1编译此代码:
struct S { };
template<typename T> struct ST { };

template<typename BaseType>
class ref_count : private BaseType { };

template<typename RefCountType>
class rep_base : public RefCountType { };

class wrap_rep : public rep_base<ref_count<S> > {
  typedef rep_base<ref_count<S> > base_type;      // line 11
};
我明白了:
bug.cpp:1: error: ‘struct S’ is inaccessible
bug.cpp:11: error: within this context
但是,如果我改变
wrap_rep
类使用
ST
class wrap_rep : public rep_base<ref_count< ST<int> > > {
  typedef rep_base<ref_count< ST<int> > > base_type;
};
它编译得很好。或者,如果我将原始代码更改为:
class wrap_rep : public rep_base<ref_count<S> > {
  typedef rep_base<ref_count< ::S > > base_type;  // now using ::
};
它也编译好。对我来说,原始代码看起来很好。这是一个g ++错误吗?如果没有,那么为什么使用模板工作呢?而且,对于另一种情况,为什么需要ѭ6?     
已邀请:
这两个代码都是无效的(只有最后一个有效),但是你的编译器(不符合)只能诊断一个。正如另一个答案所说,这使用了注入的类名。类
S
被认为具有成员名称
S
表示相同的类。例如(注意第一个例子中
S::S
之前的“class”关键字是强制引用注入的类名而不是默认构造函数所必需的):
class S { };

class S::S object; // creates an S object
class X : S::S::S::S { }; // derives from class S
类模板还具有注入的类名。与注入的类名一样,它继承到派生类,因此
ST<int>
是不正确的,因为它使用了注入的类名,但是无法访问。如果你使用GCC减去4.5,它可能与GCC4.5引入的更改有关:   G ++现在实现DR 176.以前G ++不支持使用模板基类的inject-class-name作为类型名称,并且查找名称在封闭范围内找到模板的声明。现在查找名称会找到inject-class-name,它可以用作类型或模板,具体取决于名称后面是否有模板参数列表。由于此更改,以前接受的某些代码可能格式不正确,因为         注入类名不可访问,因为它来自私有基础,或   inject-class-name不能用作模板模板参数的参数。         在这两种情况中,可以通过添加嵌套名称说明符来明确命名模板来修复代码。第一个可以使用-fno-access-control解决;第二个只是被拒绝了。 为了让注入的类名更有趣 - 请注意注入的类名不等于首先想到的typedef。注入的类名是类名,但不归类为typedef-name,这意味着它可以被函数,对象或枚举器名称隐藏:
// valid, the data-member hides the injected class name
struct S { int S; };
要引用注入的类名,你可以说
class S::S
(同样,在基类列表中,非类型名称被忽略,因此你不需要特别的预警),但是对
S::S
的简单查找将参考数据成员。     
你的结构
S
wrap_rep
的基类,这意味着它被注入
wrap_rep
,好像有一个匿名的typedef。 在你的typedef中使用
S
之前的运算符
::
将告诉编译器不要使用你继承的
S
,而是使用全局命名空间中的
S
。 看到这个链接。     
原始代码在“Sun WorkShop 6 update 2 Compilers C ++”中编译得很好。这是我在办公室里唯一可以访问的。可以试试你拥有的任何其他编译器。     

要回复问题请先登录注册