Item 44: refactor the parameter-independent code outside the Template

Source: Internet
Author: User

Item 44: refactor the parameter-independent code outside the Template

Item 44: Factor parameter-independent code out of templates.

Template is a good thing. You can write less Code while implementing type security. However, the template provides polymorphism during the compilation period. Even if your code looks very concise and short, the generated binary file may contain a large amount of redundant code. Because the template generates a complete copy each time it is instantiated, the code bloat is caused by the code that is irrelevant to the template parameters ).

Refactoring the code irrelevant to the parameters in the template outside the template can effectively control the code expansion generated by the template. In addition, code expansion can also be generated by type template parameters:

  • For code expansion caused by non-type template parameters, use function parameters or data members instead of template parameters to eliminate redundancy;
  • For the code expansion generated by the type template parameters, different instantiated template classes can share the same binary representation. Extract public code

    To avoid code redundancy, we use the commonality and variability analysis Method every day. When you write several functions, the public part is extracted to another function. When you declare a class, the public part is also extracted to the parent class.

    So you want to use this method in template programming to avoid code duplication, but the template and non-template code are different in this regard:

    • Explicit redundancy in non-template code ). You will see the code as long as there is repeated code;
    • In Template code, redundancy is implicit (implicit ). There is only one template code, and the redundancy generated when the template is instantiated requires your intuition to feel it. Template-generated code Expansion

      Now let's take a look at how a template causes code expansion. For example, to implement a fixed-size matrix, it supports transpose operations.

      template
            
             class Square{public:    void invert();};
            

      Theint nIs a non-type parameter, it is also a valid template parameter ~

      Then the template may be used as follows:

      Square
            
              s1;Square
             
               s2;s1.invert();    s2.invert();
             
            

      SquareThe template instantiates two classes:Square AndSquare , They have the sameinvertMethod. This is a typical scenario for template Generation Code expansion.

      Extract parent Template

      The Code expansion produced by the ending template is still a method of extracting public code. If you see two identicalinvertFunction. Your intuition must be to extract it to another class:

      template
            
             class SquareBase{protected:    void invert(int size);};template
             
              class Square:private SquareBase
              
               {private:    using SquareBase
               
                ::invert;public:    void invert(){ this->invert(n); }}
               
              
             
            

      BecauseinvertThe function is defined in the base class, so it only appears once in binary code, that isSquareBase ::invert . This function is shared by two sub-classes. Some details in the above Code are worth mentioning:

      • SquareBase::invertIs used for subclass, so the declaration isprivateInsteadpublic;
      • Call parent classinvertThe cost is zero becauseSquare::invertIs an implicit inline function, see Item 30;
      • Usethis->The prefix is because,SquareBaseIn the subclass TemplateSquareIs hidden, see Item 43;
      • UseprivateInheritance is because,SquareIs implemented in termsSquare, See Item 39. Data storage problems

        Since we decided to do it by the parent classinvertOperation. How does the parent class access data? Because the data is originally in the subclass. Of course, we can callSquareBase::invertThe memory address is also the parent class, But what if many functions in the matrix class need this information? We may need to pass this information to the parent class function when calling each function. In this case, why not place the data address directly in the parent class? Since the parent class stores data, we can store the matrix size together!

        template
                
                 class SquareBase{protected:    SquareBase(int _n, T *_data): n(_n), data(_data){}    void setData(T *_data){        data = _data;    }private:    int n;    T* data;};
                

        The parent class stores the location of the matrix data (data) And size (n), Subclass can still decide how to allocate address space. It can be stored in the subclass as a member attribute or dynamically applied for memory.

        Trade-offs

        No matter how data is allocated and accessed, the solution for eliminating code duplication is fixed: extract the public part to the parent template class. This solution avoids code expansion, reduces the size of binary files and "working set", improves the hit rate of instruction cache, and achieves higher code execution efficiency. However, extracting the public part to the new template class also causes some problems:

        • Ifint nThe compiler can optimize hard encoding in template parameters, such as constant propagation. Howeverint nAs a function parameter, these optimizations are gone.
        • Adding a class level will increase the object size. At least oneT* dataPointer.

          In practice, whether or not public code should be extracted depends on your application scenario. weigh the advantages and disadvantages of the above.

          This topic discusses non-type template parameters. For type template parameters, code expansion also exists, such

          • intAndlongMost platforms share the same underlying implementation, but templates are instantiated into two copies because they have different types.
          • List ,List ,List The underlying implementation is the same. However, because the pointer types are different, they are also instantiated into multiple template classes.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.