我知道基类模板的成员名称隐藏在派生类的范围内,因此必须使用this->foo
或Base<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
为什么这不起作用?
答案 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>::x
为int&
类型或可转换为int&
类型。 否则,如果您想再次避免使用this->
,我看不到其他选项。