zoukankan      html  css  js  c++  java
  • Curiously recurring template pattern

    转自stackoverflow和wiki

      In short, CRTP is when a class A has a base class which is a template specialization for the class A itself. E.g.

    template <class T> class X{...};
    class A : public X<A> {...};

    It is curiously recurring, isn't it? :)

    Now, what does this give you? This actually gives the X template the ability to be a base class for its specializations.

    For example, you could make a generic singleton class (simplified version) like this

    template <class ActualClass> 
    class Singleton
    {
       public:
       static ActualClass& GetInstance()
       {
          if(p == 0)
             p = new ActualClass;
          return *p; 
       }
    
       protected:
       static Actualclass* p;
       private:
       Singleton(){}
       Singleton(Singleton const &);
       Singleton& operator = (Singleton const &); 
    };
    template <class T>
    T* Singleton<T>::p = 0;

    Now, in order to make an arbitrary class A a singleton you should do this

    class A: public Singleton<A>
    {
       //Rest of functionality 
    };

    So you see? The singleton template assumes that its specialization for any type X will be inherited from singleton<X> and thus will have all its(public, protected) members accessible, including the GetInstance! There are other useful uses of CRTP. For example, if you want to count all instances that currently exist for your class, but want to encapsulate this logic in a separate template (the idea for a concrete class is quite simple - have a static variable, increment in ctors, decrement in dtors). Try to do it as an excercise!

    Yet another useful example, for boost(I am not sure how they have implemented it, but CRTP will do too). Imagine you want to provide only operator < for your classes but automatically operator == for them!

    you could do it like this:

    template<class Derived>
    class Equality
    {
    };
    
    template <class Derived>
    bool operator == (Equality<Derived> const& op1, Equality<Derived> const & op2)
    {
        Derived const& d1 = static_cast<Derived const&>(op1);//you assume this works     
        //because you know that the dynamic type will actually be your template parameter.
        //wonderful, isnit it?
        Derived const& d2 = static_cast<Derived const&>(op2); 
        return !(d1 < d2) && !(d2 < d1);//assuming derived has operator <
    }

    Now you can use it like this

    struct Apple:public Equality<Apple> 
    {
        int size;
    };
    
    bool operator < (Apple const & a1, Apple const& a2)
    {
        return a1.size < a2.size;
    }

    now, you haven't provided explicitly operator == for apple? But you have it! You can write

    int main()
    {
        Apple a1;
        Apple a2; 
    
        a1.size = 10;
        a2.size = 10;
        if(a1 == a2) //the compiler won't complain! 
        {
        }
    }

    This could seem that you would write less if you just wrote operator == for Apple, but imagine that the Equality template would provide not only == but >, >=, <= etc. And you could use these definitions formultiple classes, reusing the code!

    CRTP is a wonderful thing :) HTH

    stackoverflow地址

    wiki地址

  • 相关阅读:
    vue doubleclick 鼠标双击事件
    我是如何通过CSRF拿到Shell的
    js生成一个不重复的ID的函数的进化之路
    浅谈企业内部安全漏洞的运营(一):规范化
    如何让微信丢骰子永远只出“666”
    全能无线渗透测试工具,一个LAZY就搞定了
    关于8月31日维基解密被攻击的观察与分析
    VS2013 单元测试(使用VS2013自带的单元测试)
    解决WCF部署到IIS出现“证书必须具有能够进行密钥交换的私钥,该进程必须具有访问私钥的权限”
    VS2013 MVC Web项目使用内置的IISExpress支持局域网内部机器(手机、PC)访问、调试
  • 原文地址:https://www.cnblogs.com/cavehubiao/p/3892069.html
Copyright © 2011-2022 走看看