La keyword typename
Consideriamo il seguente esempio:
template < class T >
class TMyTemplate {
public:
/* ... */
private:
T::TId Object;
};
E` chiaro dall'esempio che l'intenzione era quella di utilizzare un tipo dichiarato
all'interno di T per istanziarlo all'interno del template.
Tale codice puo` sembrare corretto, ma in effetti il compilatore non produrra`
il risultato voluto. Il problema e` che il compilatore non puo` sapere in anticipo
se T::TId e` un identificatore di tipo o un qualche membro pubblico
di T .
Per default il compilatore assume che TId sia un membro pubblico
del tipo T e` l'unico modo per ovviare a cio` e` utilizzare la
keyword typename introdotta dallo standard:
template < class T >
class TMyTemplate {
public:
/* ... */
private:
typename T::TId Object;
};
La keyword typename indica al compilatore che l'identificatore
che la segue deve essere trattato come un nome di tipo, e quindi nell'esempio
precedente Object e` una istanza di tale tipo. Si ponga attenzione
al fatto che typename non sortisce l'effetto di una typedef ,
se si desidera dichiarare un alias per T::TId il procedimento da
seguire e` il seguente:
template < class T >
class TMyTemplate {
public:
/* ... */
private:
typedef typename T::TId Alias;
Alias Object
};
Un altro modo corretto di utilizzare typename e` nella dichiarazione
di template:
template < typename T >
class TMyTemplate {
/* ... */
};
In effetti se teniamo conto che il significato di class
in una dichiarazione di template e` unicamente quella di indicare un nome di
tipo che e` parametro del template e che tale parametro puo` non essere una
classe (ma anche int o una struct , o un qualsiasi
altro tipo), si capisce come sia piu` corretto utilizzare typename
in luogo di class . La ragione per cui spesso troverete class
invece di typename e` che prima dello standard tale keyword non
esisteva.
|