Dependent type are data types which depend on the template parameter. These dependent types are accessed via scope resolution operator.
template<typename T>
class MFPointer
{
public:
typedef T* ptype;
};
In above example, the member “ptype” is dependent scope datatype. This is defined inside a Template class MFPointer<T> and actual datatype (T*) depends on template parameter T. For instance, for MFPointer<int>, the ptype shall become int* and for MFPointer<float>, the ptype will be float*.
To use or access the ptype, the program shall use an expression with scope resolution operator, like, “MFPointer<int>::ptype”
Variable Declaration using Dependent type:
In the above example, ptype is actually a data type which was defined by typedef. We may use this datatype to write any declaration of any variable. Example,
typename MFPointer<T>::type m;
The declaration of “m” makes sense only if Pointer<T>::ptype is a datatype, however, there is no guarantee for this. This is because Pointer<T>::ptype may also be a static data member or enum.
To ensure C++ compiler that program knows that this is a datatype and not anything else (a static variable or enum variable or member variable), the keyword typename must precede the declaration . This keyword gives guarantee that iterator is a type.
Example:
#include <iostream> //main header
using namespace std; //namespace
template<typename T>
class MFPointer
{
public:
typedef T* ptype;
};
template<typename T>
void funda(T tx)
{
MFPointer<T>::ptype m; //Wrong declaration
//typename MFPointer<T>::ptype m; //Right declaration
}
int main()
{
int ii;
funda(ii); //Instantiation as funda<int>
return 0;
}
In this example,
- funda(ii) takes a argument of type integer. Therefore, the parameter T of template “funda<T>” will resolve to become integer (funda<int>).
- This “funda” template function internally uses a dependent scope type to declare a variable. The “MFPointer<T>::ptype”, therefore, becomes “MFPointer<int>::ptype”.
- Ultimately, “MFPointer<int>::ptype” becomes “int*”
The compiler will generate error:
Negative Scenario : ptype is not a type
Following example shows ptype is static variable for MFPointer<int> specialization. Such design may lead of potential issues, therefore, usage of “typename” help in identifying the issues during debugging.
template<typename T>
class MFPointer
{
public:
typedef T* ptype;
};
template<>
class MFPointer<int>
{
public:
static int ptype = 0;
};
Any usage of dependent scope type with typename keyword shall make the code readable. The user shall understand that they are referring to a type or non-type. The declaration cannot work for MFPointer<int> as ptype is non-type.
typename MFPointer<int>::type m; //Wrong
typename MFPointer<char>::type n; //Right