"Using" directive fails within template
I understand that the member names o开发者_如何学编程f a base-class template are hidden within the scope of a derived class, and therefore must be accessed using this->foo
or Base<T>::foo
. However, I recall that C++ also allows you to use the using
keyword, which can come in handy in a derived-class function which frequently accesses a base-class variable. So, in order to avoid cluttering up the function with this->
everywhere, I'd like to use the using
keyword.
I know I've done this before, but for whatever reason I can't get it to work now. I'm probably just doing something stupid, but the following code won't compile:
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;
}
The error, (with GCC 4.3) is: error: ‘Base<T>’ is not a namespace
Why doesn't this work?
It doesn't work because C++ language has no such feature and never had. A using-declaration for a class member must be a member declaration. This means that you can only use in class scope, but never in local scope. This all has absolutely nothing to do with templates.
In other words, you can place your using-declaration into class scope
struct Derived : public Base<T> {
...
using Base<T>::x;
...
};
but you can't have it inside a function.
Using-declarations for namespace members can be placed in local scope, but using-declarations for class members cannot be. This is why the error message complains about Base<T>
not being a namespace.
Outside class scope (if you are in a block etc), you can only name namespace members in a using declaration.
If you don't want to place that using declaration into the scope of Derived
(which IMO is the favorable solution), your other option is to use a reference
int &x = this->x;
x = 0;
It should be noted that this is semantically different, because it
- Forces a definition to exist for
Base<T>::x
, which might not be the case for static const data members - Forces
Base<T>::x
to be of typeint&
or be convertible to typeint&
.
Otherwise, if you want to avoid using this->
all again, I don't see other options.
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;
}
As others said, it is working only class scope.
精彩评论