9

我这里有一个旧代码库,他们使用受保护的成员变量。这是否是一个好主意可以讨论。但是,代码必须用 gcc3 编译得很好。我有一个派生模板类 Bar,它使用类模板 Foo 中的受保护成员 x 像这样

template <class Something> class Foo {  
public:  
// stuff...  
protected:  
  some::type x;  
}

template <class Something> Bar : Foo<Something> {
public:
  void cleanup();
}

在 cleanup() 的方法声明中,x 做了一些事情

template <class Something> void Bar<Something>::cleanup() {
  doSomeThingCleanUpLike (x);
}

这不适用于 gcc4,尽管它应该适用于 gcc3。当我将其更改为

doSomeThingCleanUpLike (this->x);

为什么会这样?

4

2 回答 2

14

根据标准中的规则,派生类中使用的表达式x不依赖于派生类的任何模板参数。因此,查找发生在模板定义的上下文中,而不是在使用/实例化点。即使模板的模板基类看起来是可见的,因为它是一个模板类,可能使用的特定实例化可能涉及专门的模板,因此基类模板定义不能用于名称查找。

通过将表达式更改为this->x您正在使其成为依赖表达式(this在类模板中始终取决于模板参数)。这意味着查找将发生在实例化上下文中,此时基类是完全已知的并且其成员是可见的。

于 2009-10-26T13:06:47.453 回答
6

当你定义派生模板时,编译器只知道基模板类的名称而不知道它的细节,所以编译器不知道派生类有一个继承的成员。为了告诉编译器该成员的存在,使用this->,就像你做的那样。

实际上,它是这个问题的副本。

于 2009-10-26T12:56:08.660 回答