c + + template -- basic knowledge

After the first two lectures, I want to introduce the basic knowledge of c + + templates more comprehensively. This lecture will assume that you have the basic knowledge of the last two lectures.

1. Key sub typename

        In the process of c + + standardization, the key sub typename is introduced to illustrate that the identifier inside the template can be a type

  For example:

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

  The second typename indicates that SubType is a type defined inside class T

If there is no declaration of the second typename, write it directly in the following form

T::SubType* ptr;

The compiler will think: SubType   It is a static member variable in class T, so the above code will be interpreted as:

T: : product of subtype and PTR (T::SubType)   *  ptr)

two   . Template construction (note the small points before the template)

Let's look at examples first

template<int N>
void printBitset(std::bitset<N> const& bs){
    std::cout<<bs.template to_string<char,char_traits<char>,allocator<char> >();

You will find a strange thing bs.template. In fact, we want to call it like this

bs.to_string<char,char_traits<char>,allocator<char> >();

bs is an STD:: BitSet < n > const & type object. We want to call to.string under this object

But there is a problem, how does the compiler distinguish between the following <, > which is the template < >, or the larger <, >

Therefore, the. template structure is used to tell the compiler that the < >, which you see later, is not a relatively large < >

3. Use - > this


template <typename T>
class Base {
    void exit();

template <typename T>
class Derived : Base<T> {
    void foo() {
        exit(); //Call external exit() or report an error directly

If called directly, the compiler will either report an error or call other exit() functions with the same name. Anyway, it will not call the exit() function inherited from the parent class

If you want to call a function inherited from the parent class, you should write it like this


4. Member template

A member in a template class can also be a template


template <typename T>
class Stack {
    std::deque<T> elems;//Container for storing elements

    void push(T const&);//Push 
    void pop();//Out of stack
    T top() const;//Return stack top element
    inline bool empty() const { return elems.empty(); }

    //The stack with element type T2 is used for assignment
    template <typename T2>
    Stack<T>& operator= (Stack<T2> const&);

template<typename T>
template<typename T2>
Stack<T>& Stack<T>::operator= (Stack<T2> const& op2) {
    if((void*)this == (void*)&op2) {//We don't want to assign values to ourselves
        return *this;

    Stack<T2> tmp(op2); //Copy a copy

    elems.clear(); //Empty existing elements

    return *this;

5. Template parameters of template

It's quite long. I wrote a separate article

6. Zero initialization

We hope that when we use a template, even if we do nothing, its internal initialization has been done to avoid some unexpected things.

//For function templates
template<typename T>
void f() {
    T x = T();
    //Adding T is int, that is, int x = int();, In this way, x will be initialized to 0

//For class templates
template<typename T>
class MyClass {
    T x;
    MyClass() : x(...) {//Confirm that x is initialized, as are other built-in object types

7. Use the string as the argument of the function template

Sometimes there are unexpected things when passing a string to the reference of a function template, which is related to the type derivation of the template and the degradation of the array. If you don't know what I'm talking about, you can see my related articles

Type derivation of template

Type derivation of auto

give an example

#include <string>

template<typename T>
inline T const& max (T const& a, T const& b) {
    return a < b ? a : b;

int main() {
    std::string s();

    ::max("apple", "peach"); //Correct, same type parameter
    ::max("apple", "tomato");//Error, different type parameters
    ::max("apple", s);//Error, arguments of different types

Because it is T const&,So arrays don't degenerate.
that apple and peach yes const char[6]type
tomato yes const char[7]type
s It's a string type

A good solution is to overload max() for the string.

Tags: C++

Posted on Tue, 19 Oct 2021 16:18:28 -0400 by houssam_ballout