When a template class inherits from another template class, typedefs in the base class must be redefined again (i.e. they are not automatically inherited), and function calls in the base class need to be qualified. Why is that? Isn't this already unambiguous?
So if I have 20 template classes, all defining the same typedefs, I am not able to introduce a base class containing these definitions them and inherit from it, as I have to redefine the typedefs anyway in every class, which defeats the purpose. This is makes the source code so unnecessarily verbose.
I can see this has been discussed in this question, but I do not understand the comment
The C++ name lookup rules specify that a name is only searched in a templated base classes if it depends on a template parameter (if it is a "dependent name"). If a name does not depend on a template parameter it isn't searched there.
What is the reason for this? It makes no sense to me.
Perhaps, the following code snippet would illustrate my question better:
#include <iostream>
template <unsigned N, typename T>
struct A
{
typedef T U;
static void foo(T x) { std::cout << N + x << "\n"; }
};
template <unsigned N, typename T>
struct B : public A<N, T>
{
// Why do I have to redeclare U? Isn't is unambiguous already?
typedef typename A<N, T>::U U;
// why do I have to specify B::? Isn't it unambiguous already?
static void zoo(U x) { B::foo(x); }
};
int main()
{
B<2,int>().zoo(3);
B<2,double>().zoo(3.5);
return 0;
}
Inheriting from a template classIt is possible to inherit from a template class. All the usual rules for inheritance and polymorphism apply. If we want the new, derived class to be generic it should also be a template class; and pass its template parameter along to the base class.
What are Class Templates in C++? Templates are the mechanism by which C++ implements the generic concept. Simply, they allow you to pass data type as a parameter so that you don't need to write the same code for different data types.
There is no difference between using <typename T> OR <class T> ; i.e. it is a convention used by C++ programmers.
An individual class defines how a group of objects can be constructed, while a class template defines how a group of classes can be generated. Note the distinction between the terms class template and template class: Class template. is a template used to generate template classes.
That's happening because of two phase lookup. Quote from here:
- Template definition time: when the template is initially parsed, long before it is instantiated, the compiler parses the template and looks up any "non-dependent" names. A name is "non-dependent" if the results of name lookup do not depend on any template parameters, and therefore will be the same from one template instantiation to another.
- Template instantiation time: when the template is instantiated, the compiler looks up any "dependent" names, now that it has the full set of template arguments to perform lookup. The results of this lookup can (and often do!) vary from one template instantiation to another.
So, during initial parsing compiler thinks that U
is non-dependent name and tries to look it up and it can't find anything because it isn't allowed to look into the dependent base class. But if U
were dependent name then compiler would look it up during instantiation phase and would find it in the base class.
BTW: VS will readily compile this, but they have added possibility of two phase lookup lately.
The fundamental reason is that classes can be specialized:
template<class T>
struct A {};
template<class T>
struct B : A<T> {
typedef typename A<T>::referent target;
void niceName() {A<T>::uglyName();}
};
template<class T>
struct A<T*> {
typedef T referent;
void uglyName();
};
B<int*>::target i; // OK: int
Of course, the reverse case (where the primary template defines useful things, and we simply fear that a specialization might change or remove them) is more common, which makes the rule seem arbitrary.
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