Core knowledge of C + + 11-17 template (XII) — template parameters of template

Time:2021-9-10
  • concept
  • give an example
  • Template template argument matching
    • Solution 1
    • Solution 2

concept

The parameter of a template is the template type.

give an example

In the core knowledge of C + + 11-17 template (II) – class template, if we want to allow us to specify the container for storing stack elements, we do so:

template > 
class Stack {
private:
  Cont elems; // elements
  ......
};

use:

Stack> dblStack;

However, the disadvantage is that you need to specify the element type twice, but the two types are the same.

Using the template parameters of the template allows us to specify only the type of container instead of the container when declaring the stack class template
The type of the element. For example:

template  class Cont = std::deque>
class Stack {
private:
  Cont elems; // elements
public:
  void push(T const &); // push element
  void pop();           // pop element
  T const &top() const; // return top element
  bool empty() const {  // return whether the stack is empty
    return elems.empty();
  }
  ...
};

use:

Stack vStack;      // integer stack that uses a vector

The difference from the first method is that the second template parameter is a class template:

template class Cont

Default value fromstd::dequeChange tostd::deque.

After C + + 17, the class in the template parameters of the template can also use typename, but struct and union cannot be used:

template  typename Cont = std::deque>
class Stack {       // ERROR before C++17
  ...
};

......

template class C> // OK
void f(C* p);

template struct C> // ERROR: struct not valid here
void f(C* p);

template union C> // ERROR: union not valid here
void f(C* p);

Of course, since the elem in the template parameters of the template is not used, it can be omitted:

template  class Cont = std::deque> 
class Stack {
  ...
};

In addition, note that the template parameters in the template parameters of the template can only be used with the template parameters of the template. A little spare, for example:

template class Buf>        // OK
class Lexer {
    static T* storage;        // ERROR: a template template parameter cannot be used here
    ...
};

Template template argument matching

You can try to compile the above code yourself. The following problems may occur:

error: template template argument has different template parameters than its corresponding template template parameter
template  class Cont = std::deque>

...

/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/deque:1197:1: note: too many template parameters in template template argument
template */>

intendstd::dequeandContNo match. Standard librarystd::dequeThere are two parameters and a default parameter allocator:

template  > class _LIBCPP_TEMPLATE_VIS deque;

Solution 1

Match the parameters of cont and STD:: deque:

template >
          class Cont = std::deque>
class Stack {
......
};

Alloc here is not used and can also be omitted.

Example of member function definition:

template class Cont>
void Stack::push (T const& elem) {
    elems.push_back(elem);       // append copy of passed elem
}

Solution 2

Using the core knowledge of C + + 11-17 template (IV) — variable parameter template

template 
          class Cont = std::deque>
class Stack {
......
};

But this is forstd::arrayInvalid because the second parameter of STD:: array is a non type template parameter nontype template parameters:

// template
// class array;

If usedStack s;, the compiler will report an error:

/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/array:126:29: note: template parameter has a different kind in template argument
template 
                            ^
main.cc:22:33: note: previous template template parameter is here
          template 
                                ^

(end)

Friends can take note of my official account and get the most timely updates.

image

Recommended Today

The selector returned by ngrx store createselector performs one-step debugging of fetching logic

Test source code: import { Component } from ‘@angular/core’; import { createSelector } from ‘@ngrx/store’; export interface State { counter1: number; counter2: number; } export const selectCounter1 = (state: State) => state.counter1; export const selectCounter2 = (state: State) => state.counter2; export const selectTotal = createSelector( selectCounter1, selectCounter2, (counter1, counter2) => counter1 + counter2 ); // […]