I am going over the WildMagic 5 engine (www.geometrictools.com) where the Vector<> class is inheriting from a Tuple<> class which has an array of a particular size, named mTuple[]
(set by a template parameter). So far so good, nothing special. In the Vector class however, I see the following:
protected:
using Tuple<4,Real>::mTuple;
Now I know that the using
keyword is used for inheriting overloaded methods properly. In this case, I always assumed the variable was available to the derived class without typing the above code. Is the above necessary? Or is it just there to make things clearer?
The base keyword is used to access members of the base class from within a derived class: Call a method on the base class that has been overridden by another method. Specify which base-class constructor should be called when creating instances of the derived class.
And C++ doesn't have a super or base keyword to designate “the base class”, like C# and Java do. One reason for this is that C++ supports multiple inheritance, which would make such a keyword ambiguous.
As with so many techniques in C++, it is largely a matter of syntax. When you want to call a specific base class's version of a virtual function, just qualify it with the name of the class you are after, as I did in Example 8-16: p->Base::foo();
The using keyword is used to: Bring a specific member from the namespace into the current scope. Bring all members from the namespace into the current scope. Bring a base class method or variable into the current class's scope.
Generic programming is slightly different from object oriented programming.
Your mTuple
is an example of a nondependent name. As far as the compiler is concerned, at the time the template definition is processed the compiler doesn't know that the class template has inherited a data member named mTuple
. It might be obvious to you, but it is not obvious to the compiler. At this stage, the compiler is oblivious to the obvious.
If the methods of the derived class template wish to use some member of the parent class template, the compiler needs to be explicitly told to do so. Hence the using
.
Edit
The above was a bit terse. It is important to remember that those class templates are not classes. They are templates that eventually define a class. Up until the moment that the class template is used to define a class that class template isn't quite real. More importantly, for a class template that inherits from some other class template, that inheritance isn't quite real. The compiler doesn't know about that inheritance unless it is explicitly told about it. That's why you will see derived class templates import the parent class's members via using ParentClass<Type>::member
(for example).
Edit #2
Marshall Cline discusses this topic in his C++-FAQ at http://www.parashift.com/c++-faq-lite/templates.html#faq-35.19
Edit #3
(Per request) Just because some code compiles on your compiler does not mean it compiles on every compiler (for the same language). Compiler vendors add their own 'features' to a language, sometimes very intentionally, sometimes just because the vendors themselves goofed up, and sometimes because the standard itself is buggy. This issue of not-quite-standard compilers has been a problem for a long time, with many languages. The problem apparently is quite rampant when it comes to generic programming.
You can do everything right (or so you think): Turn on all standard warnings and then some, run your code through some commercial code analyzer, and you still might not have portable code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With