Interpreting the three specialities of class templates in C++ programming

  • 2020-05-07 20:12:39
  • OfStack

1. Class template explicit specialization
The   heap is a linearized tree structure. Pressing a value into a heap is equivalent to inserting the value into a tree structure. Remove a value from the heap is removed and returned to the heap maximum. But in the treatment of the character pointer will be disheartened. Pile will be carried out in accordance with the pointer the value of the organization. We can provide an explicit specialization version (1) to solve the problem if you want to in addition to 1 for const char Heap *, also want to provide one for char * Heap; (2)


// The master template 
template <typename T>
class Heap
{
private:
  std::vector<T> h_;
public:
  void push(const T& val);
  T pop();
  bool empty() const //const The declaration at the end indicates that the function cannot modify a class variable 
  {
    return h_.empty();
  }
}

template <typename T>
void Heap<T>::push(const T& val)
{
  h_.push_back(val);
  std::push_heap(h_.begin(),h_.end());
}

template <typename T>
T Head<T>::pop()
{
  std::pop_head(h_.begin(),h_.end());
  T tmp(h_.back());
  h_.pop_back();
  return tmp;
}

Case 1


// Display the specialized version 
/***********************************************
 *      You can see that the template parameter list is empty , It's not 1 A die 
 *   plate .  Because no template parameters are specified . So the explicit specialization of the template is again 
 *   Referred to as " Complete specialization ".
 *     Heap<const char*>  Complete specialization , Does not cause the template to be instantiated ;
 *     Heap<int>  specialized , This causes the template to be instantiated ;
 *      The compiler checks for class template specialization based on the declaration of the master template .
***********************************************/
template<>// Pay attention to , No parameters , Of course, , It's not 1 A template 
class Head<const char *>
{
private:
  std::vector<const char *> h_;
public:
  void push(const char *pval);
  const char * pop();
  bool empty() const //const The declaration at the end indicates that the function cannot modify a class variable 
  {
    return h_.empty();
  }
};
// Once again remind , Head<const char *> not 1 A template 
void Heap<const char*>::push(const char *pval)
{
  h_.push_back(pval);
  std::push_heap(h_.begin(),h_.end());
}

Case 2


/***********************************************
 *     C++ There is no requirement that an explicitly specialized interface be complete with the interface of the main template 
 *   matching . As in this case , There is no master template defined empty function , And it increases on its own 
 *   the size and capitalize Two functions .
 *      remind : Not defined in this example empty Functions are not desirable , template-defining 
 *   There is no technical connection between explicit specialization and class derivation , but 
 *   Is the advantage that users can still refer to the derivation of the class , Make the specialized version at least available 
 *   Basic capabilities of the master template .
***********************************************/
template<>// Pay attention to , No parameters , Of course, , It's not 1 A template 
class Head<char *>
{
private:
  std::vector<char *> h_;
public:
  void push(char *pval);
  char * pop();
  // Pay attention to , Not provided here empty Function yo !!!
  size_t size() const;
  void capitalize();
};

2. Local specialization of templates
template partial specialization must first statement, C + + does not support the function template partial specialization, so here we only discuss the class template partial specialization. We still need a master template first. (refer to explicit specialization class template) self understanding: if for cannot be completely specialized pointer define different is not too much trouble, is there a better way to do the & # 63; That's local specialization.(example 1) tip: local specialization is a template. Complete specialization is not a template.

Case 1


/***********************************************
 *   Partial specialization  
 *      It's not like a complete specialization , Here, Heap Parameter types are only partially true 
 *   As the T*, while T is 1 Three unspecified types , That's why it's local, right 
 *   The reason for specialization ;
 *      When using 1 An unmodified pointer type to instantiate Heap when ,
 *   Local specialization will take precedence over the master template ;
 *      When using const char *  or  char *( The reference class template is explicitly specialized ) to 
 *   instantiation Heap when , In this case, complete specialization will take precedence over local specialization .
 *  Heap<std::string> h1;   The master template   T is std::string
 *  Heap<std::string *> h2;   Partial specialization   T is std:string
 *  Heap<int **> h3;     Partial specialization  T is int *
 *  Heap<char *> h4;   Complete specialization  T is char *
 *  Heap<const int *> h5;   Partial specialization  T is const int
 *  Heap<int (*)()> h6;   Partial specialization  T is int()
***********************************************/
template <typename T>
class Heap<T *> // Note that there 
{
private:
  std::vector<T *>h_;
public:
  void push(const T *val);
  T *pop();
  bool empty()
  {
    return h_.empty();
  }
};

template <typename T>
void Heap<T *>::push(const T *val)
{
  //......
}

Case 2


/***********************************************
 *      There are 1 The point is subtle but useful : Full or partial specialization of the master template 
 *   You must instantiate with the same number and type of arguments as the main template , But it 
 *   The parameters of the template do not need to have the same form as the main template .
***********************************************/
// define 1 A template , There are 3 Template parameters , Written as follows 
template <typename R,typename A1,typename A2> 
// Pay attention to , Local specialization , Template parameters are also 3 a , But not in writing 1 Sample after ather 
class Heap<R (*) (A1,A2)>
{
  //......
};

Heap<char *(*) (int,int)> h7; //R is char *,A1 and A2 is int
// the  char *(*) (int,int)  To imagine 1 a " A pointer to a nonmember function that takes two arguments "

template <class C,typename T>
class Heap<T C::*>
{
  //......
};
Heap<std::string Name::*> h8;//T is string,C is Name

Although it's only a guess why you need to use Heap for these things, let's be aware of the usage.

3. Class template member specialization

Although there is no relationship between the specialization of a template and the derivation of a class, it is useful to refer to the spirit of derivation under 1 when specializing a template.
Ex. :


// The master template 
template <typename T>
class Heap
{
private:
  std::vector<T> h_;
public:
  void push(const T& val);
  T pop();
  bool empty() const //const The declaration at the end indicates that the function cannot modify a class variable 
  {
    return h_.empty();
  }
}
// What we really need to specialize  push  and  pop Two functions .
// Contrast explicit specialization , It is through the master template , To write 1 Five template explicitly specialized version classes ;
// This is just a separate specialization of the class template members .
template<>
void Heap<const char*>::push(const char *const &pval)
{
  h_.push_back(pval);
  std::push_heap(h_.begin(),h_.end(),strLess);
}

template<>
const char* Heap<const char*>::pop()
{
  std:pop_heap(h_.begin(),h_end(),strLess);
  const char* tmp = h_.back();
  h_.pop_back();
  return tmp;
}


Interface must note that these function and they are specialized its members "of the template matches the corresponding interface. Such as case 1, and the master template matching interface. If you are yourself again an explicit/local specialized versions of the definition of class, there is no need to match 1. (see explicit specialization and partial specialization), the last two points: first, in addition to a member function, but members can also be an explicit specialization, such as static members and member templates. Second, explicit specialization is to provide customized version of the template or templates member 1 way; Whereas explicit instantiation simply explicitly tells the compiler to de-instantiate a member.              


Related articles: