C ++ template (template) in typename

1, typename keyword

  When you declare a template parameter, prefix the keyword class and typename are interchangeable, but can only be used when the internal typename type name using the template parameter T that is nested dependent name.

  In the C ++ standardization process, the introduction of keywords typenameto illustrate: internal template type parameter identifier (associated type, common in various STL containers) may also be a type:

  such as:

template<typename T>
class MyClass
{
    typename T::SubType* ptr;
}

  Introduce a few concepts within the template parameter names here;

  Slave name (dependent names): name that appears in the template (Template), dependent on a template (Template) parameters, such as T t;

  nested dependent name (nested dependent names): dependent name in the form of a nested class, the T :: const_iterator ci;

  non-subject name (non-dependent names): name of template does not depend on any parameters, such as the int value;   any time referent in a nested dependent type name template (template), it is necessary a previous position add the keyword typename;
  

  If not specifically stated typename, nested slave name, parsing may occur (the parse) ambiguity, may be error (GCC): error: need 'typename' before 'T :: xxx' because 'T' is a dependent scope.

  such as:

template<typename T>
class MyClass
{
    /*typename*/ T::SubType* ptr;
}

  In the above procedure, the second typename is used to illustrate, with the SubType is a type of class defines the interior T, i.e. associated type, therefore, a pointer PTR is pointer type T :: SubType. If you do not use typename, T :: SubType priority will be seen as a static member T, which is a specific and variable or object, so the following expression:

T::SubType* ptr;

  At this time, the compiler will not be able to distinguish what is this SubType, because SubType may be a static variable in the template parameter T, ptr can be seen as a global variable, then the code will be seen as the product of the static SubType member of class T and the ptr or it may be a typedef for example SubType

class Class_T{
    typedef int SubType;
    ...
};

  The above code is converted into one that is this:

int *x;

 

2, the use of several nested dependent name of scene typename

  a, if the template name appears in the templates is dependent on a parameter, called the slave name (dependent name). If the slave name in the form of a nested class, we called nesting slave name (nested dependent name), for example as follows:

template<typename T>
void print(const T & container)
{
    T::const_iterator iter(container.begin());
    cout << *iter << endl;
    int value = *iter;
    return;
}
  • In the above code, the ITER type template-dependent parameter T, it is called dependent name;
  • Similarly, value type is built into the language type, the template does not depend on any parameters, it is called non-subject name;
  • C ++ compiler in the face of a slave name, if this time the slave name and other types of nested, so that at the iter T :: const_iterator type, where T :: const_iterator called a nested dependent type name (nested in T type, belonging to the template parameter T)

 or

template<typename T> // typename allowed (as is "class")
void f(const T& container, // typename not allowed typename T::iterator iter); // typename required

  Above T is not nested dependent type name (it is not nested within any "depends on a template parameter" thing), so when the container does not need to be declared as a leading typename.
However, T :: iterator is nested dependent type name, as it must typename preamble.
  

  b, when a template class inside typedef types, if this type associated with the template parameter T, you need to use typename. That is the form:

Template < class T>
 class the Test 
{ 
public : 
 typedef Map < int , T> TEMPLATE_MAP; // TEMPLATE_MAP not need typename, because it does not rely on other names 
 typedef Map < int , T> :: Iterator TEMPLATE_MAP_ITER;   // error fitted! sets slave name, independent of other iterator class name 
 typedef typename Map < int , T> :: iterator TEMPLATE_MAP_ITER; // Yes  
};

 

   C, exceptions: nested dependent type name, if the list of base classes (base class list) and a member of the initial value columns (member initialization list) is not used typename;

/*
 * BInsertSort.cpp
 *
 *  Created on: 2014.4.17
 *      Author: Spike
 */
 
#include <iostream>
#include <vector>
 
using namespace std;
 
struct Number {
    Number(int x) {
        std::cout << "Number = " << x << std::endl;
    }
};
 
template<typename T>
struct Base{
    typedef Number Nested;
};
 
template<typename T>
class Derived: public Base<T>::Nested { // do typename 
public :
     Explicit the Derived ( int X): Base <T> :: the Nested (X) { // do typename 
        typename Base <T> :: the Nested TEMP ( . 7 ); // must 
    } 
}; 
 
int main () { 
    the Derived < int > D ( . 5 ); 
 
    return  0 ; 
}

 

Guess you like

Origin www.cnblogs.com/kerngeeksund/p/10700747.html