1

When inheriting from a template class, I need to prefix all base class members I access in the derived class with this:

template<typename T>
struct X{
   int foo;
   void bar();
};

template<typename T>
struct Y : public X<T> {

   void blub(){
       foo++; // Does not work
       this->foo++; // Fine
       bar(); // Does not work
       this->bar(); // Fine
   }
}

As I was hinted, the reason why you must prefix the members with this has already been answered HERE. So my remaining question is: Is there a way to avoid all the thises? For example, I have a method in the derived class that uses a lot of base class members. The code looks totally cluttered with all the this-> in it. Is there a way to omit these?

Community
  • 1
  • 1
gexicide
  • 37,012
  • 19
  • 88
  • 143
  • 3
    It's explained in a million places on Stack Overflow, just search around for five (more) minutes. – user541686 Aug 20 '14 at 10:46
  • @Mehrdad: I tried to search for my question first. I could not find it. In addition, is there a way to get around it? – gexicide Aug 20 '14 at 10:48
  • Good search keyword: "dependent names" – Angew is no longer proud of SO Aug 20 '14 at 10:48
  • @Angew: Didn't know about these keywords. However, I tried searching for "C++ dependent names" and "template this dependent names" and got no matching results. – gexicide Aug 20 '14 at 10:50
  • @gexicide You can get around it with a `using` declaration. See the canonical ["Where and why do I have to put the “template” and “typename” keywords? "](http://stackoverflow.com/q/610245/1782465). – Angew is no longer proud of SO Aug 20 '14 at 10:50
  • possible duplicate of [Why do I have to access template base class members through the this pointer?](http://stackoverflow.com/questions/4643074/why-do-i-have-to-access-template-base-class-members-through-the-this-pointer) – Constructor Aug 20 '14 at 10:51
  • @Angew: How can it be avoided with `using`? That would be interesting, but I cannot find it in the question you linked. – gexicide Aug 20 '14 at 10:52
  • @Constructor: Interesting, yes, that question explains it. But it does not give a hint whether and how it can be avoided. – gexicide Aug 20 '14 at 10:52
  • 1
    @gexicide Write `using X::foo;` in your `Y` class template. – Constructor Aug 20 '14 at 10:55
  • I have rephrased the question so it only asks how it can be circumvented, not why it is the case. I have added a link to the question that explains why. @Constructor: Interesting, I will try that. You can also phrase it as answer if you want. – gexicide Aug 20 '14 at 10:56

1 Answers1

7

To make this work, you need to turn the non-dependent names foo and bar into dependent names. There are three ways to do this:

  • Qualify them with this, as you have done. This has the downside that you need to do it everywhere you use the names. this is implicitly a dependent name.
  • Qualify them with the base class name, as X<T>::foo and X<T>::bar. This also needs to be done everywhere you use them, and additionally breaks the virtual dispatch mechanism if they turn out to be virtual methods.
  • Bring the dependent names into the non-dependent namespace by using X<T>::foo; and using X<T>::bar;.

Or, you can compile with VC++ which couldn't care less about the distinction between dependent and non-dependent names.

Tom
  • 6,617
  • 1
  • 36
  • 59
  • @Drax My life is currently hell because of this. I'm porting a large code base from VC++ to GCC. The rest of the team is still developing in VC++. It doesn't matter how often you explain the dependent/non-dependent distinction to them, they keep on breaking it and can't see what's wrong. "But it compiles fine for me..." – Tom Aug 20 '14 at 23:53
  • Is the thing about VC++ still true today? Because it doesn't seem to work. Maybe there's some option for it? – SWdV Apr 12 '19 at 22:23