Error "Use" in the template

I understand that the base class template member names are hidden within the class of the derived class and therefore must be accessible using this->foo or Base<T>::foo . However, I remember that C ++ also allows you to use the using keyword, which can be useful in a function of a derived class, which often accesses a base class variable. So, to avoid messing up the function with this-> everywhere, I would like to use the using keyword.

I know I did this before, but for some reason I can't get it to work now. I'm probably just doing something stupid, but the following code will not 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; } 

Error (with GCC 4.3): error: 'Base<T>' is not a namespace

Why is this not working?

+4
source share
3 answers

This does not work, because the C ++ language does not have such a function and has never been. A usage declaration for a class member must be a member declaration. This means that you can only use in the scope of the class, but never in the local scope. All this is absolutely not related to templates.

In other words, you can put your usage declaration in the class scope

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

but you cannot use it inside a function.

Using-declarations for members of a namespace can be placed in a local scope, but using-declarations for members of a class cannot be. This is why the error message complains that Base<T> not a namespace.

+7
source
 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 have said, it only works with the scope of the class.

+3
source

An external class (if you are in a block, etc.), you can only namespace member names in a usage declaration.

If you don’t want to place this using an ad in the Derived (which IMO is a favorable solution), another option is to use the link

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

It should be noted that this is semantically different because it

  • Makes the definition exist for Base<T>::x , which may not be the case for static const data members
  • The forces Base<T>::x are of type int& or can be convertible of type int& .

Otherwise, if you want to no longer use this-> , I do not see other parameters.

+3
source

Source: https://habr.com/ru/post/1333056/


All Articles