Why can't my Curiously Recurring Template Pattern (CRTP) refer to the derived class's typedefs? [duplicate]

让人想犯罪 __ 提交于 2019-12-04 09:40:41

This is the "circular dependecies", or "incomplete-type" alter-ego.

Template "meta-programming" is "programming types", but it requires a certain level of sematics to be known to properly instantiate types.

Consider this analogy:

class A; //forwarded

class B
{
   A* pa; //good: we know how wide a pointer is, no matter if we don't know yet anything about A.
   A a; // bad: we don't know how much space it requires
};

class A
{
  float m;
}; // now we know, but it's too late

This can be solved by placing A before B, but if A is

class A
{
   B m;
};

Thhere is no other solution than pointers, since A recursion will be infinite. (A should contain itself, not refer to another copy)

Now, with the same analogy, let's program "types":

template<class D>
class A
{
   typedef typename D::inner_type my_type; //required D to be known when A<D> is instantiated...
   my_type m; // ... otherwise we cannot know how wide A<D> will be.
};

This declaration is not itself bad,until we start to define D as ...

class D: //here we only know D exist
    public A<D> //but A size depende on D definition...
{
  ....
  typedef long double; inner_type
  ....
}; // ....we know only starting from here

So, basically, we don't know (yet) how wide is A at the time need to use it to create D.

One way to break this "circularity" is to use some "traits classes" outside of the CRT loop:

struct traits
{
   typedef long double inner_type;
   ....
};

template<class D, class Traits>
class A
{
  // this is easy: Traits does not depend itself on A
  typedef typename Traits::inner_type my_type;
  ....
};

template<class Traits>
class D: public A<D, Traits>
{
  typedef typename Traits::inner_type inner_type;
};

An we can finally declare

typedef D<traits> D_Inst;

In other words, the coherence between A::my_type and D::inner_type is ensured by traits::inner_type, whose definition is independent.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!