当前位置:网站首页>Core knowledge of C + + 11-17 template (14) -- Analysis of template dependent template name (. Template / - & gt; template /:: template)

Core knowledge of C + + 11-17 template (14) -- Analysis of template dependent template name (. Template / - & gt; template /:: template)

2020-12-08 14:31:46 Zhang Yachen

If you have time, please read the last article first : c++11-17 Template core knowledge ( 13、 ... and )—— Name search and ADL

tokenization And parsing

Most languages compile in two phases :

  • tokenization, Or call it scanning/lexing
  • parsing

tokenization The phase reads the source code and generates a series of token. for example :int *p = 0;,tokenizer Will generate keywords int、 Operator *、 identifier p、 Operator =、 Integers 0、 Operator ;

Next ,parser Will recursively reduce the token , Looking for known patterns . for example :token 0 It's a legal expression ,*p Combination is also a legal statement , It and the back =0 Combination is also a legal Initialization declaration . Last ,int It's a known type , Follow behind Initialization declaration : *p=0, therefore , We get an initialization p Statement of

Resolves the dependency name of the type of template Dependent Names of Templates

There are six aspects to template parsing :

  • Context dependency in non templates Context Sensitivity in Nontemplates
  • Dependent type name Dependent Names of Types
  • Dependent template name Dependent Names of Templates <-----
  • using-declaration The dependency name in the Dependent Names in Using Declarations
  • ADL And explicit template arguments ADL and Explicit Template Arguments
  • Dependency expressions Dependent Expressions

This article begins with the third common point in the code : Dependent template name (Dependent Names of Templates)

Here's an important concept : stay c++11-17 Template core knowledge ( 13、 ... and )—— Name search and ADL As described in Dependent Name: Depends on the name of the template parameter , That is, the expression type on the left side of the access operator depends on the template parameter . for example :std::vector ::iterator It's a Dependent Name, But if T Is an alias of a known type (using T = int), That is not Dependent Name.

generally , The compiler will put the template name after < As the beginning of the template parameter list , otherwise ,< It's the comparison operator . however , When the referenced template name is Dependent Name when , The compiler does not assume that it is a template name , Unless the display uses template Key words to indicate , Template code in common ->template.template::template It's applied to this scenario .

Here are a few examples .

Example One

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

here , Parameters bs Depends on template parameters N. therefore , We have to pass template Keywords let the compiler know bs It's a template name , Otherwise, according to the above rules ,< Will be treated as a comparator —— Less than no. .

Example Two

The template keyword as qualifier (C++ only) Examples in :

#include <iostream>
using namespace std;

class X {
   public:
      template <int j> struct S {
         void h() {
            cout << "member template's member function: " << j << endl;
         }
      };
      template <int i> void f() {
        cout << "Primary: " << i << endl;
      }
};

template<> void X::f<20>() {
   cout << "Specialized, non-type argument = 20" << endl;
}

template<class T> void g(T* p) {
   p->template f<100>();
   p->template f<20>();
   typename T::template S<40> s; // use of scope operator on a member template
   s.h();
}

int main()
{
   X temp;
   g(&temp);
}

here , Parameters p Depending on template parameters T. Be careful typename T::template S<40> s; Use .

Example Three

template <typename T> class Shell {
public:
  template <int N> class In {
  public:
    template <int M> class Deep {
    public:
      virtual void f();
    };
  };
};

template <typename T, int N> class Weird {
public:
  void case1(typename Shell<T>::template In<N>::template Deep<N> *p) {
    p->template Deep<N>::f();      // inhibit virtual call
  }

  void case2(typename Shell<T>::template In<N>::template Deep<N> &p) {
    p.template Deep<N>::f();      // inhibit virtual call
  }
};

Parameters p Depending on template parameters T. The compiler doesn't judge p.Deep Is it a template . If you don't specify template, that p.Deep<N>::f() It will be interpreted as ((p.Deep)<N)>f();,< As a comparator .

Based on the above example , We can also know ,->template.template::template Only exists in templates , And in Dependent Name Used in the scene of ( Depends on template parameters ).

( End )

Friends can pay attention to my official account , Get the most up-to-date updates :

image

版权声明
本文为[Zhang Yachen]所创,转载请带上原文链接,感谢
https://chowdera.com/2020/12/20201208143134839j.html