1.When the template type parameter is declared, class and typename have the same meaning.
2. If the name in the template depends on a template parameter, it is calledDependent names)If the subordinate name is nested in the classNested subordinate name.
Nested subordinate names may cause resolution difficulties, such:
Template <typename C> void print2nd (const C & container) {C: const_iterator * X; // you may declare an iterator, it may also be a multiplication operation ...}
C ++'s rule for parsing such ambiguity is:If the parser encounters a nested slave name in the template, it assumes that the name is not of a type, unless explicitly declared that it is. This rule has one exception: typename cannot appear before the nested subordinate type name in the base class list, nor can it be used as the base class modifier in the member initialization list. The explicit declaration method is to add the typename keyword before it.:
Template <typename T> class derived: public base <t >:: nested {// The base class list does not allow typenamepublic: explicit derived (int x): Base <t> :: nested (x) {// The member initialization list does not allow typenametypename base <t>: Nested temp; // neither in the base class list nor in the member initialization list, as a base class modifier, you need to add typename ...}...};
Note that typename is only used to indicate nested subordinate types. Non-nested subordinate types should not exist.
3. When the involved typename declarative type is too long, you can use typedef:
template<typename IterT>void workWithIterator(IterT iter){typedef typename std::iterator_traits<IterT>::value_type value_type;value_type temp(*iter);...}
4. typename rules have different implementation methods on different compilers. Therefore, the use of typename may reduce portability.