“使用”指令在模板中失败

时间:2010-12-22 15:40:04

标签: c++ templates using

我知道基类模板的成员名称隐藏在派生类的范围内,因此必须使用this->fooBase<T>::foo进行访问。但是,我记得C ++还允许您使用using关键字,它可以在派生类函数中派上用场,该函数经常访问基类变量。因此,为了避免在任何地方使用this->混乱功能,我想使用using关键字。

我知道我以前做过这件事,但无论出于何种原因我现在都无法上班。我可能只是做了一些愚蠢的事情,但以下代码无法编译:

template <class T>
struct Base
{
   int x;
};

template <class T>
struct Derived : public Base<T>
{
   void dosomething()
   {
     using Base<T>::x; // gives compiler error
     x = 0;
   }
};

int main()
{
   Derived<int> d;
}

错误(使用GCC 4.3)是:error: ‘Base<T>’ is not a namespace

为什么这不起作用?

3 个答案:

答案 0 :(得分:7)

它不起作用,因为C ++语言没有这样的功能,从来没有。类成员的using声明必须是成员声明。这意味着您只能在类范围内使用,但绝不能在本地范围内使用。这一切都与模板完全无关。

换句话说,您可以将using声明放入类范围

struct Derived : public Base<T> {
  ...
  using Base<T>::x;
  ...
};

但你不能把它放在一个函数中。

命名空间成员的使用声明可以放在本地范围内,但类成员的使用声明不能。这就是错误消息抱怨Base<T>不是命名空间的原因。

答案 1 :(得分:3)

template <class T>
struct Base
{
   int x;
};

template <class T>
struct Derived : public Base<T>
{
   using Base<T>::x;
   void dosomething()
   {
     x = 0;
   }
};

int main()
{
   Derived<int> d;
}

正如其他人所说,它只适用于班级范围。

答案 2 :(得分:3)

外部类范围(如果您在块中等),您只能在using声明中命名命名空间成员。

如果您不想将声明放在Derived的范围内(IMO是有利的解决方案),您的另一个选择是使用参考

int &x = this->x;
x = 0;

应该注意,这在语义上是不同的,因为它

  • 强制Base<T>::x存在定义,静态const数据成员可能不是这种情况
  • 强制Base<T>::xint&类型或可转换为int&类型。

否则,如果您想再次避免使用this->,我看不到其他选项。